diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ae57b7fddc1..f02cf704d1b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Report a bug about: Create a report to help us improve labels: kind/bug, priority/P2 -assignees: karthikravis +assignees: nicolasnoble --- diff --git a/.github/ISSUE_TEMPLATE/cleanup_request.md b/.github/ISSUE_TEMPLATE/cleanup_request.md index 72a5c267257..11e8be8ef3e 100644 --- a/.github/ISSUE_TEMPLATE/cleanup_request.md +++ b/.github/ISSUE_TEMPLATE/cleanup_request.md @@ -2,7 +2,7 @@ name: Request a cleanup about: Suggest a cleanup in our repository labels: kind/internal cleanup, priority/P2 -assignees: karthikravis +assignees: nicolasnoble --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 12315263911..fb3dae79227 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Request a feature about: Suggest an idea for this project labels: kind/enhancement, priority/P2 -assignees: karthikravis +assignees: nicolasnoble --- diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 681d2f819ce..57af6c21597 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -8,4 +8,4 @@ If you know who should review your pull request, please remove the mentioning be --> -@karthikravis +@nicolasnoble diff --git a/BUILD b/BUILD index 4a29654fc35..58148f58dab 100644 --- a/BUILD +++ b/BUILD @@ -1236,6 +1236,21 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc_grpclb_balancer_addresses", + srcs = [ + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc", + ], + hdrs = [ + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h", + ], + language = "c++", + deps = [ + "grpc_base", + "grpc_client_channel", + ], +) + grpc_cc_library( name = "grpc_lb_policy_grpclb", srcs = [ @@ -1256,6 +1271,7 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", + "grpc_grpclb_balancer_addresses", "grpc_lb_upb", "grpc_resolver_fake", "grpc_transport_chttp2_client_insecure", @@ -1282,6 +1298,7 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", + "grpc_grpclb_balancer_addresses", "grpc_lb_upb", "grpc_resolver_fake", "grpc_secure", @@ -1619,6 +1636,7 @@ grpc_cc_library( deps = [ "grpc_base", "grpc_client_channel", + "grpc_grpclb_balancer_addresses", "grpc_resolver_dns_selection", ], ) diff --git a/BUILD.gn b/BUILD.gn index ee40a4db057..306f2bfa6d8 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -229,6 +229,8 @@ config("grpc_config") { "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc", + "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f644900723..5a52205e480 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -161,7 +161,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") if(MSVC) include(cmake/msvc_static_runtime.cmake) @@ -447,7 +447,7 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_c check_gcp_environment_linux_test) add_dependencies(buildtests_c check_gcp_environment_windows_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_dependencies(buildtests_c client_ssl) + add_dependencies(buildtests_c client_ssl_test) endif() add_dependencies(buildtests_c cmdline_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) @@ -481,10 +481,10 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_c fd_posix_test) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_dependencies(buildtests_c fling) + add_dependencies(buildtests_c fling_stream_test) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_dependencies(buildtests_c fling_stream) + add_dependencies(buildtests_c fling_test) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c fork_test) @@ -497,10 +497,10 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_c grpc_completion_queue_test) add_dependencies(buildtests_c grpc_ipv6_loopback_available_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_dependencies(buildtests_c handshake_server_with_readahead_handshaker) + add_dependencies(buildtests_c handshake_server_with_readahead_handshaker_test) endif() if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_dependencies(buildtests_c handshake_verify_peer_options) + add_dependencies(buildtests_c handshake_verify_peer_options_test) endif() add_dependencies(buildtests_c histogram_test) add_dependencies(buildtests_c host_port_test) @@ -555,7 +555,7 @@ if(gRPC_BUILD_TESTS) add_dependencies(buildtests_c sequential_connectivity_test) add_dependencies(buildtests_c server_chttp2_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_dependencies(buildtests_c server_ssl) + add_dependencies(buildtests_c server_ssl_test) endif() add_dependencies(buildtests_c server_test) add_dependencies(buildtests_c slice_buffer_test) @@ -1319,6 +1319,7 @@ add_library(grpc src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc @@ -1972,6 +1973,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc @@ -4619,11 +4621,11 @@ endif() if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_executable(client_ssl + add_executable(client_ssl_test test/core/handshake/client_ssl.cc ) - target_include_directories(client_ssl + target_include_directories(client_ssl_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -4635,7 +4637,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_ZLIB_INCLUDE_DIR} ) - target_link_libraries(client_ssl + target_link_libraries(client_ssl_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -5279,15 +5281,15 @@ endif() if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_executable(fling + add_executable(fling_stream_test test/core/end2end/data/client_certs.cc test/core/end2end/data/server1_cert.cc test/core/end2end/data/server1_key.cc test/core/end2end/data/test_root_cert.cc - test/core/fling/fling_test.cc + test/core/fling/fling_stream_test.cc ) - target_include_directories(fling + target_include_directories(fling_stream_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -5299,7 +5301,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_ZLIB_INCLUDE_DIR} ) - target_link_libraries(fling + target_link_libraries(fling_stream_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -5314,15 +5316,15 @@ endif() if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_executable(fling_stream + add_executable(fling_test test/core/end2end/data/client_certs.cc test/core/end2end/data/server1_cert.cc test/core/end2end/data/server1_key.cc test/core/end2end/data/test_root_cert.cc - test/core/fling/fling_stream_test.cc + test/core/fling/fling_test.cc ) - target_include_directories(fling_stream + target_include_directories(fling_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -5334,7 +5336,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_ZLIB_INCLUDE_DIR} ) - target_link_libraries(fling_stream + target_link_libraries(fling_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -5589,12 +5591,12 @@ endif() if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_executable(handshake_server_with_readahead_handshaker + add_executable(handshake_server_with_readahead_handshaker_test test/core/handshake/readahead_handshaker_server_ssl.cc test/core/handshake/server_ssl_common.cc ) - target_include_directories(handshake_server_with_readahead_handshaker + target_include_directories(handshake_server_with_readahead_handshaker_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -5606,7 +5608,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_ZLIB_INCLUDE_DIR} ) - target_link_libraries(handshake_server_with_readahead_handshaker + target_link_libraries(handshake_server_with_readahead_handshaker_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -5621,11 +5623,11 @@ endif() if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_executable(handshake_verify_peer_options + add_executable(handshake_verify_peer_options_test test/core/handshake/verify_peer_options.cc ) - target_include_directories(handshake_verify_peer_options + target_include_directories(handshake_verify_peer_options_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -5637,7 +5639,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_ZLIB_INCLUDE_DIR} ) - target_link_libraries(handshake_verify_peer_options + target_link_libraries(handshake_verify_peer_options_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc @@ -6850,12 +6852,12 @@ endif() if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) - add_executable(server_ssl + add_executable(server_ssl_test test/core/handshake/server_ssl.cc test/core/handshake/server_ssl_common.cc ) - target_include_directories(server_ssl + target_include_directories(server_ssl_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -6867,7 +6869,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_ZLIB_INCLUDE_DIR} ) - target_link_libraries(server_ssl + target_link_libraries(server_ssl_test ${_gRPC_ALLTARGETS_LIBRARIES} grpc_test_util grpc diff --git a/Makefile b/Makefile index e82afad3ed5..08ee1cbe217 100644 --- a/Makefile +++ b/Makefile @@ -1040,7 +1040,7 @@ channel_stack_builder_test: $(BINDIR)/$(CONFIG)/channel_stack_builder_test channel_stack_test: $(BINDIR)/$(CONFIG)/channel_stack_test check_gcp_environment_linux_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test check_gcp_environment_windows_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test -client_ssl: $(BINDIR)/$(CONFIG)/client_ssl +client_ssl_test: $(BINDIR)/$(CONFIG)/client_ssl_test cmdline_test: $(BINDIR)/$(CONFIG)/cmdline_test combiner_test: $(BINDIR)/$(CONFIG)/combiner_test completion_queue_threading_test: $(BINDIR)/$(CONFIG)/completion_queue_threading_test @@ -1062,8 +1062,8 @@ fake_resolver_test: $(BINDIR)/$(CONFIG)/fake_resolver_test fake_transport_security_test: $(BINDIR)/$(CONFIG)/fake_transport_security_test fd_conservation_posix_test: $(BINDIR)/$(CONFIG)/fd_conservation_posix_test fd_posix_test: $(BINDIR)/$(CONFIG)/fd_posix_test -fling: $(BINDIR)/$(CONFIG)/fling -fling_stream: $(BINDIR)/$(CONFIG)/fling_stream +fling_stream_test: $(BINDIR)/$(CONFIG)/fling_stream_test +fling_test: $(BINDIR)/$(CONFIG)/fling_test fork_test: $(BINDIR)/$(CONFIG)/fork_test format_request_test: $(BINDIR)/$(CONFIG)/format_request_test frame_handler_test: $(BINDIR)/$(CONFIG)/frame_handler_test @@ -1072,8 +1072,8 @@ grpc_alts_credentials_options_test: $(BINDIR)/$(CONFIG)/grpc_alts_credentials_op grpc_byte_buffer_reader_test: $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test grpc_completion_queue_test: $(BINDIR)/$(CONFIG)/grpc_completion_queue_test grpc_ipv6_loopback_available_test: $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test -handshake_server_with_readahead_handshaker: $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker -handshake_verify_peer_options: $(BINDIR)/$(CONFIG)/handshake_verify_peer_options +handshake_server_with_readahead_handshaker_test: $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker_test +handshake_verify_peer_options_test: $(BINDIR)/$(CONFIG)/handshake_verify_peer_options_test histogram_test: $(BINDIR)/$(CONFIG)/histogram_test host_port_test: $(BINDIR)/$(CONFIG)/host_port_test hpack_encoder_test: $(BINDIR)/$(CONFIG)/hpack_encoder_test @@ -1114,7 +1114,7 @@ secure_endpoint_test: $(BINDIR)/$(CONFIG)/secure_endpoint_test security_connector_test: $(BINDIR)/$(CONFIG)/security_connector_test sequential_connectivity_test: $(BINDIR)/$(CONFIG)/sequential_connectivity_test server_chttp2_test: $(BINDIR)/$(CONFIG)/server_chttp2_test -server_ssl: $(BINDIR)/$(CONFIG)/server_ssl +server_ssl_test: $(BINDIR)/$(CONFIG)/server_ssl_test server_test: $(BINDIR)/$(CONFIG)/server_test slice_buffer_test: $(BINDIR)/$(CONFIG)/slice_buffer_test slice_string_helpers_test: $(BINDIR)/$(CONFIG)/slice_string_helpers_test @@ -1417,7 +1417,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/channel_stack_test \ $(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test \ $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test \ - $(BINDIR)/$(CONFIG)/client_ssl \ + $(BINDIR)/$(CONFIG)/client_ssl_test \ $(BINDIR)/$(CONFIG)/cmdline_test \ $(BINDIR)/$(CONFIG)/combiner_test \ $(BINDIR)/$(CONFIG)/completion_queue_threading_test \ @@ -1439,8 +1439,8 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/fake_transport_security_test \ $(BINDIR)/$(CONFIG)/fd_conservation_posix_test \ $(BINDIR)/$(CONFIG)/fd_posix_test \ - $(BINDIR)/$(CONFIG)/fling \ - $(BINDIR)/$(CONFIG)/fling_stream \ + $(BINDIR)/$(CONFIG)/fling_stream_test \ + $(BINDIR)/$(CONFIG)/fling_test \ $(BINDIR)/$(CONFIG)/fork_test \ $(BINDIR)/$(CONFIG)/format_request_test \ $(BINDIR)/$(CONFIG)/frame_handler_test \ @@ -1449,8 +1449,8 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test \ $(BINDIR)/$(CONFIG)/grpc_completion_queue_test \ $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test \ - $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker \ - $(BINDIR)/$(CONFIG)/handshake_verify_peer_options \ + $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker_test \ + $(BINDIR)/$(CONFIG)/handshake_verify_peer_options_test \ $(BINDIR)/$(CONFIG)/histogram_test \ $(BINDIR)/$(CONFIG)/host_port_test \ $(BINDIR)/$(CONFIG)/hpack_encoder_test \ @@ -1491,7 +1491,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/security_connector_test \ $(BINDIR)/$(CONFIG)/sequential_connectivity_test \ $(BINDIR)/$(CONFIG)/server_chttp2_test \ - $(BINDIR)/$(CONFIG)/server_ssl \ + $(BINDIR)/$(CONFIG)/server_ssl_test \ $(BINDIR)/$(CONFIG)/server_test \ $(BINDIR)/$(CONFIG)/slice_buffer_test \ $(BINDIR)/$(CONFIG)/slice_string_helpers_test \ @@ -1910,8 +1910,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test || ( echo test check_gcp_environment_linux_test failed ; exit 1 ) $(E) "[RUN] Testing check_gcp_environment_windows_test" $(Q) $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test || ( echo test check_gcp_environment_windows_test failed ; exit 1 ) - $(E) "[RUN] Testing client_ssl" - $(Q) $(BINDIR)/$(CONFIG)/client_ssl || ( echo test client_ssl failed ; exit 1 ) + $(E) "[RUN] Testing client_ssl_test" + $(Q) $(BINDIR)/$(CONFIG)/client_ssl_test || ( echo test client_ssl_test failed ; exit 1 ) $(E) "[RUN] Testing cmdline_test" $(Q) $(BINDIR)/$(CONFIG)/cmdline_test || ( echo test cmdline_test failed ; exit 1 ) $(E) "[RUN] Testing combiner_test" @@ -1954,10 +1954,10 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/fd_conservation_posix_test || ( echo test fd_conservation_posix_test failed ; exit 1 ) $(E) "[RUN] Testing fd_posix_test" $(Q) $(BINDIR)/$(CONFIG)/fd_posix_test || ( echo test fd_posix_test failed ; exit 1 ) - $(E) "[RUN] Testing fling" - $(Q) $(BINDIR)/$(CONFIG)/fling || ( echo test fling failed ; exit 1 ) - $(E) "[RUN] Testing fling_stream" - $(Q) $(BINDIR)/$(CONFIG)/fling_stream || ( echo test fling_stream failed ; exit 1 ) + $(E) "[RUN] Testing fling_stream_test" + $(Q) $(BINDIR)/$(CONFIG)/fling_stream_test || ( echo test fling_stream_test failed ; exit 1 ) + $(E) "[RUN] Testing fling_test" + $(Q) $(BINDIR)/$(CONFIG)/fling_test || ( echo test fling_test failed ; exit 1 ) $(E) "[RUN] Testing fork_test" $(Q) $(BINDIR)/$(CONFIG)/fork_test || ( echo test fork_test failed ; exit 1 ) $(E) "[RUN] Testing format_request_test" @@ -1974,10 +1974,10 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/grpc_completion_queue_test || ( echo test grpc_completion_queue_test failed ; exit 1 ) $(E) "[RUN] Testing grpc_ipv6_loopback_available_test" $(Q) $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test || ( echo test grpc_ipv6_loopback_available_test failed ; exit 1 ) - $(E) "[RUN] Testing handshake_server_with_readahead_handshaker" - $(Q) $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker || ( echo test handshake_server_with_readahead_handshaker failed ; exit 1 ) - $(E) "[RUN] Testing handshake_verify_peer_options" - $(Q) $(BINDIR)/$(CONFIG)/handshake_verify_peer_options || ( echo test handshake_verify_peer_options failed ; exit 1 ) + $(E) "[RUN] Testing handshake_server_with_readahead_handshaker_test" + $(Q) $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker_test || ( echo test handshake_server_with_readahead_handshaker_test failed ; exit 1 ) + $(E) "[RUN] Testing handshake_verify_peer_options_test" + $(Q) $(BINDIR)/$(CONFIG)/handshake_verify_peer_options_test || ( echo test handshake_verify_peer_options_test failed ; exit 1 ) $(E) "[RUN] Testing histogram_test" $(Q) $(BINDIR)/$(CONFIG)/histogram_test || ( echo test histogram_test failed ; exit 1 ) $(E) "[RUN] Testing host_port_test" @@ -2054,12 +2054,10 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/secure_endpoint_test || ( echo test secure_endpoint_test failed ; exit 1 ) $(E) "[RUN] Testing security_connector_test" $(Q) $(BINDIR)/$(CONFIG)/security_connector_test || ( echo test security_connector_test failed ; exit 1 ) - $(E) "[RUN] Testing sequential_connectivity_test" - $(Q) $(BINDIR)/$(CONFIG)/sequential_connectivity_test || ( echo test sequential_connectivity_test failed ; exit 1 ) $(E) "[RUN] Testing server_chttp2_test" $(Q) $(BINDIR)/$(CONFIG)/server_chttp2_test || ( echo test server_chttp2_test failed ; exit 1 ) - $(E) "[RUN] Testing server_ssl" - $(Q) $(BINDIR)/$(CONFIG)/server_ssl || ( echo test server_ssl failed ; exit 1 ) + $(E) "[RUN] Testing server_ssl_test" + $(Q) $(BINDIR)/$(CONFIG)/server_ssl_test || ( echo test server_ssl_test failed ; exit 1 ) $(E) "[RUN] Testing server_test" $(Q) $(BINDIR)/$(CONFIG)/server_test || ( echo test server_test failed ; exit 1 ) $(E) "[RUN] Testing slice_buffer_test" @@ -2186,6 +2184,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_streaming_ping_pong || ( echo test bm_fullstack_streaming_ping_pong failed ; exit 1 ) $(E) "[RUN] Testing bm_fullstack_unary_ping_pong" $(Q) $(BINDIR)/$(CONFIG)/bm_fullstack_unary_ping_pong || ( echo test bm_fullstack_unary_ping_pong failed ; exit 1 ) + $(E) "[RUN] Testing bm_metadata" + $(Q) $(BINDIR)/$(CONFIG)/bm_metadata || ( echo test bm_metadata failed ; exit 1 ) $(E) "[RUN] Testing bm_pollset" $(Q) $(BINDIR)/$(CONFIG)/bm_pollset || ( echo test bm_pollset failed ; exit 1 ) $(E) "[RUN] Testing bm_timer" @@ -2206,8 +2206,6 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/channelz_registry_test || ( echo test channelz_registry_test failed ; exit 1 ) $(E) "[RUN] Testing channelz_service_test" $(Q) $(BINDIR)/$(CONFIG)/channelz_service_test || ( echo test channelz_service_test failed ; exit 1 ) - $(E) "[RUN] Testing channelz_test" - $(Q) $(BINDIR)/$(CONFIG)/channelz_test || ( echo test channelz_test failed ; exit 1 ) $(E) "[RUN] Testing cli_call_test" $(Q) $(BINDIR)/$(CONFIG)/cli_call_test || ( echo test cli_call_test failed ; exit 1 ) $(E) "[RUN] Testing client_callback_end2end_test" @@ -2216,8 +2214,6 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/client_channel_stress_test || ( echo test client_channel_stress_test failed ; exit 1 ) $(E) "[RUN] Testing client_interceptors_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/client_interceptors_end2end_test || ( echo test client_interceptors_end2end_test failed ; exit 1 ) - $(E) "[RUN] Testing client_lb_end2end_test" - $(Q) $(BINDIR)/$(CONFIG)/client_lb_end2end_test || ( echo test client_lb_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing codegen_test_full" $(Q) $(BINDIR)/$(CONFIG)/codegen_test_full || ( echo test codegen_test_full failed ; exit 1 ) $(E) "[RUN] Testing codegen_test_minimal" @@ -2234,8 +2230,6 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/destroy_grpclb_channel_with_active_connect_stress_test || ( echo test destroy_grpclb_channel_with_active_connect_stress_test failed ; exit 1 ) $(E) "[RUN] Testing duplicate_header_bad_client_test" $(Q) $(BINDIR)/$(CONFIG)/duplicate_header_bad_client_test || ( echo test duplicate_header_bad_client_test failed ; exit 1 ) - $(E) "[RUN] Testing end2end_test" - $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) $(E) "[RUN] Testing error_details_test" $(Q) $(BINDIR)/$(CONFIG)/error_details_test || ( echo test error_details_test failed ; exit 1 ) $(E) "[RUN] Testing eventmanager_libuv_test" @@ -3655,6 +3649,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \ @@ -4283,6 +4278,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \ @@ -7619,34 +7615,34 @@ endif endif -CLIENT_SSL_SRC = \ +CLIENT_SSL_TEST_SRC = \ test/core/handshake/client_ssl.cc \ -CLIENT_SSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLIENT_SSL_SRC)))) +CLIENT_SSL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLIENT_SSL_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/client_ssl: openssl_dep_error +$(BINDIR)/$(CONFIG)/client_ssl_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/client_ssl: $(CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(BINDIR)/$(CONFIG)/client_ssl_test: $(CLIENT_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/client_ssl + $(Q) $(LDXX) $(LDFLAGS) $(CLIENT_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/client_ssl_test endif $(OBJDIR)/$(CONFIG)/test/core/handshake/client_ssl.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -deps_client_ssl: $(CLIENT_SSL_OBJS:.o=.dep) +deps_client_ssl_test: $(CLIENT_SSL_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(CLIENT_SSL_OBJS:.o=.dep) +-include $(CLIENT_SSL_TEST_OBJS:.o=.dep) endif endif @@ -8353,28 +8349,28 @@ endif endif -FLING_SRC = \ +FLING_STREAM_TEST_SRC = \ test/core/end2end/data/client_certs.cc \ test/core/end2end/data/server1_cert.cc \ test/core/end2end/data/server1_key.cc \ test/core/end2end/data/test_root_cert.cc \ - test/core/fling/fling_test.cc \ + test/core/fling/fling_stream_test.cc \ -FLING_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FLING_SRC)))) +FLING_STREAM_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FLING_STREAM_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/fling: openssl_dep_error +$(BINDIR)/$(CONFIG)/fling_stream_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/fling: $(FLING_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(BINDIR)/$(CONFIG)/fling_stream_test: $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(FLING_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling + $(Q) $(LDXX) $(LDFLAGS) $(FLING_STREAM_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_stream_test endif @@ -8386,39 +8382,39 @@ $(OBJDIR)/$(CONFIG)/test/core/end2end/data/server1_key.o: $(LIBDIR)/$(CONFIG)/l $(OBJDIR)/$(CONFIG)/test/core/end2end/data/test_root_cert.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(OBJDIR)/$(CONFIG)/test/core/fling/fling_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -deps_fling: $(FLING_OBJS:.o=.dep) +deps_fling_stream_test: $(FLING_STREAM_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(FLING_OBJS:.o=.dep) +-include $(FLING_STREAM_TEST_OBJS:.o=.dep) endif endif -FLING_STREAM_SRC = \ +FLING_TEST_SRC = \ test/core/end2end/data/client_certs.cc \ test/core/end2end/data/server1_cert.cc \ test/core/end2end/data/server1_key.cc \ test/core/end2end/data/test_root_cert.cc \ - test/core/fling/fling_stream_test.cc \ + test/core/fling/fling_test.cc \ -FLING_STREAM_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FLING_STREAM_SRC)))) +FLING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FLING_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/fling_stream: openssl_dep_error +$(BINDIR)/$(CONFIG)/fling_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/fling_stream: $(FLING_STREAM_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(BINDIR)/$(CONFIG)/fling_test: $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(FLING_STREAM_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_stream + $(Q) $(LDXX) $(LDFLAGS) $(FLING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/fling_test endif @@ -8430,13 +8426,13 @@ $(OBJDIR)/$(CONFIG)/test/core/end2end/data/server1_key.o: $(LIBDIR)/$(CONFIG)/l $(OBJDIR)/$(CONFIG)/test/core/end2end/data/test_root_cert.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -$(OBJDIR)/$(CONFIG)/test/core/fling/fling_stream_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(OBJDIR)/$(CONFIG)/test/core/fling/fling_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -deps_fling_stream: $(FLING_STREAM_OBJS:.o=.dep) +deps_fling_test: $(FLING_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(FLING_STREAM_OBJS:.o=.dep) +-include $(FLING_TEST_OBJS:.o=.dep) endif endif @@ -8715,25 +8711,25 @@ endif endif -HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_SRC = \ +HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_TEST_SRC = \ test/core/handshake/readahead_handshaker_server_ssl.cc \ test/core/handshake/server_ssl_common.cc \ -HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_SRC)))) +HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: openssl_dep_error +$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker_test: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker + $(Q) $(LDXX) $(LDFLAGS) $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_server_with_readahead_handshaker_test endif @@ -8741,43 +8737,43 @@ $(OBJDIR)/$(CONFIG)/test/core/handshake/readahead_handshaker_server_ssl.o: $(LI $(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -deps_handshake_server_with_readahead_handshaker: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS:.o=.dep) +deps_handshake_server_with_readahead_handshaker_test: $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_OBJS:.o=.dep) +-include $(HANDSHAKE_SERVER_WITH_READAHEAD_HANDSHAKER_TEST_OBJS:.o=.dep) endif endif -HANDSHAKE_VERIFY_PEER_OPTIONS_SRC = \ +HANDSHAKE_VERIFY_PEER_OPTIONS_TEST_SRC = \ test/core/handshake/verify_peer_options.cc \ -HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_VERIFY_PEER_OPTIONS_SRC)))) +HANDSHAKE_VERIFY_PEER_OPTIONS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HANDSHAKE_VERIFY_PEER_OPTIONS_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: openssl_dep_error +$(BINDIR)/$(CONFIG)/handshake_verify_peer_options_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(BINDIR)/$(CONFIG)/handshake_verify_peer_options_test: $(HANDSHAKE_VERIFY_PEER_OPTIONS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_verify_peer_options + $(Q) $(LDXX) $(LDFLAGS) $(HANDSHAKE_VERIFY_PEER_OPTIONS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/handshake_verify_peer_options_test endif $(OBJDIR)/$(CONFIG)/test/core/handshake/verify_peer_options.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -deps_handshake_verify_peer_options: $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS:.o=.dep) +deps_handshake_verify_peer_options_test: $(HANDSHAKE_VERIFY_PEER_OPTIONS_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(HANDSHAKE_VERIFY_PEER_OPTIONS_OBJS:.o=.dep) +-include $(HANDSHAKE_VERIFY_PEER_OPTIONS_TEST_OBJS:.o=.dep) endif endif @@ -10137,25 +10133,25 @@ endif endif -SERVER_SSL_SRC = \ +SERVER_SSL_TEST_SRC = \ test/core/handshake/server_ssl.cc \ test/core/handshake/server_ssl_common.cc \ -SERVER_SSL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_SSL_SRC)))) +SERVER_SSL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_SSL_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/server_ssl: openssl_dep_error +$(BINDIR)/$(CONFIG)/server_ssl_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/server_ssl: $(SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a +$(BINDIR)/$(CONFIG)/server_ssl_test: $(SERVER_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(SERVER_SSL_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_ssl + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/server_ssl_test endif @@ -10163,11 +10159,11 @@ $(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl.o: $(LIBDIR)/$(CONFIG)/libgr $(OBJDIR)/$(CONFIG)/test/core/handshake/server_ssl_common.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libupb.a -deps_server_ssl: $(SERVER_SSL_OBJS:.o=.dep) +deps_server_ssl_test: $(SERVER_SSL_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(SERVER_SSL_OBJS:.o=.dep) +-include $(SERVER_SSL_TEST_OBJS:.o=.dep) endif endif diff --git a/README.md b/README.md index d3eee331088..a392de0e7e0 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ For instructions on how to use the language-specific gRPC runtime for a project, * [Dart](https://github.com/grpc/grpc-dart): pub package `grpc` * [Go](https://github.com/grpc/grpc-go): `go get google.golang.org/grpc` * [Java](https://github.com/grpc/grpc-java): Use JARs from Maven Central Repository + * [Kotlin](https://github.com/grpc/grpc-kotlin): Use JARs from Maven Central Repository * [Node](https://github.com/grpc/grpc-node): `npm install grpc` * [Objective-C](src/objective-c): Add `gRPC-ProtoRPC` dependency to podspec * [PHP](src/php): `pecl install grpc` @@ -77,8 +78,9 @@ Libraries in different languages may be in various states of development. We are | Language | Source repo | |-------------------------|------------------------------------------------------| -| Java | [grpc-java](https://github.com/grpc/grpc-java) | -| Go | [grpc-go](https://github.com/grpc/grpc-go) | +| Java | [grpc-java](https://github.com/grpc/grpc-java) | +| Kotlin | [grpc-kotlin](https://github.com/grpc/grpc-kotlin) | +| Go | [grpc-go](https://github.com/grpc/grpc-go) | | NodeJS | [grpc-node](https://github.com/grpc/grpc-node) | | WebJS | [grpc-web](https://github.com/grpc/grpc-web) | | Dart | [grpc-dart](https://github.com/grpc/grpc-dart) | diff --git a/bazel/cython_library.bzl b/bazel/cython_library.bzl index 3f34e185380..c9f864231c1 100644 --- a/bazel/cython_library.bzl +++ b/bazel/cython_library.bzl @@ -63,12 +63,15 @@ def pyx_library(name, deps = [], py_deps = [], srcs = [], **kwargs): ) shared_objects.append(shared_object_name) + data = shared_objects[:] + data += kwargs.pop("data", []) + # Now create a py_library with these shared objects as data. native.py_library( name = name, srcs = py_srcs, deps = py_deps, srcs_version = "PY2AND3", - data = shared_objects, + data = data, **kwargs ) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 0608514bd4b..14daa48e2b7 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -385,6 +385,7 @@ libs: - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h + - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h @@ -742,6 +743,7 @@ libs: - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc + - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc @@ -1279,6 +1281,7 @@ libs: - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h + - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h @@ -1571,6 +1574,7 @@ libs: - src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc + - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc @@ -3043,7 +3047,7 @@ targets: - gpr - address_sorting - upb -- name: client_ssl +- name: client_ssl_test build: test language: c headers: [] @@ -3357,7 +3361,7 @@ targets: - linux - posix - mac -- name: fling +- name: fling_stream_test build: test language: c headers: @@ -3367,7 +3371,7 @@ targets: - test/core/end2end/data/server1_cert.cc - test/core/end2end/data/server1_key.cc - test/core/end2end/data/test_root_cert.cc - - test/core/fling/fling_test.cc + - test/core/fling/fling_stream_test.cc deps: - grpc_test_util - grpc @@ -3378,7 +3382,7 @@ targets: - linux - posix - mac -- name: fling_stream +- name: fling_test build: test language: c headers: @@ -3388,7 +3392,7 @@ targets: - test/core/end2end/data/server1_cert.cc - test/core/end2end/data/server1_key.cc - test/core/end2end/data/test_root_cert.cc - - test/core/fling/fling_stream_test.cc + - test/core/fling/fling_test.cc deps: - grpc_test_util - grpc @@ -3510,7 +3514,7 @@ targets: - gpr - address_sorting - upb -- name: handshake_server_with_readahead_handshaker +- name: handshake_server_with_readahead_handshaker_test build: test language: c headers: @@ -3528,7 +3532,7 @@ targets: - linux - posix - mac -- name: handshake_verify_peer_options +- name: handshake_verify_peer_options_test build: test language: c headers: [] @@ -4085,6 +4089,7 @@ targets: - upb - name: sequential_connectivity_test build: test + run: false language: c headers: - test/core/end2end/data/ssl_test_data.h @@ -4112,7 +4117,7 @@ targets: - gpr - address_sorting - upb -- name: server_ssl +- name: server_ssl_test build: test language: c headers: @@ -5196,7 +5201,6 @@ targets: - posix - name: bm_metadata build: test - run: false language: c++ headers: [] src: @@ -5441,6 +5445,7 @@ targets: - name: channelz_test gtest: true build: test + run: false language: c++ headers: - test/cpp/util/channel_trace_proto_helper.h @@ -5578,6 +5583,7 @@ targets: - name: client_lb_end2end_test gtest: true build: test + run: false language: c++ headers: - test/core/util/test_lb_policies.h @@ -5732,6 +5738,7 @@ targets: - name: end2end_test gtest: true build: test + run: false language: c++ headers: - test/cpp/end2end/interceptors_util.h diff --git a/config.m4 b/config.m4 index 7a38e36cd71..66922ad5527 100644 --- a/config.m4 +++ b/config.m4 @@ -53,6 +53,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ + src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \ diff --git a/config.w32 b/config.w32 index 089504a1841..541cc74b602 100644 --- a/config.w32 +++ b/config.w32 @@ -22,6 +22,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\lb_policy\\child_policy_handler.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\client_load_reporting_filter.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb.cc " + + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_balancer_addresses.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_channel_secure.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_client_stats.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\load_balancer_api.cc " + diff --git a/examples/cpp/compression/greeter_client.cc b/examples/cpp/compression/greeter_client.cc index a8428174644..99e2a5973fc 100644 --- a/examples/cpp/compression/greeter_client.cc +++ b/examples/cpp/compression/greeter_client.cc @@ -85,7 +85,7 @@ int main(int argc, char** argv) { args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP); GreeterClient greeter(grpc::CreateCustomChannel( "localhost:50051", grpc::InsecureChannelCredentials(), args)); - std::string user("world"); + std::string user("world world world world"); std::string reply = greeter.SayHello(user); std::cout << "Greeter received: " << reply << std::endl; diff --git a/examples/cpp/helloworld/CMakeLists.txt b/examples/cpp/helloworld/CMakeLists.txt index f158a75bd78..a5e2d9bb27c 100644 --- a/examples/cpp/helloworld/CMakeLists.txt +++ b/examples/cpp/helloworld/CMakeLists.txt @@ -60,7 +60,7 @@ if(GRPC_AS_SUBMODULE) else() set(_PROTOBUF_PROTOC $) endif() - set(_GRPC_GRPCPP_UNSECURE grpc++_unsecure) + set(_GRPC_GRPCPP grpc++) if(CMAKE_CROSSCOMPILING) find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) else() @@ -87,7 +87,7 @@ elseif(GRPC_FETCHCONTENT) set(_PROTOBUF_LIBPROTOBUF libprotobuf) set(_REFLECTION grpc++_reflection) set(_PROTOBUF_PROTOC $) - set(_GRPC_GRPCPP_UNSECURE grpc++_unsecure) + set(_GRPC_GRPCPP grpc++) if(CMAKE_CROSSCOMPILING) find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) else() @@ -116,7 +116,7 @@ else() find_package(gRPC CONFIG REQUIRED) message(STATUS "Using gRPC ${gRPC_VERSION}") - set(_GRPC_GRPCPP_UNSECURE gRPC::grpc++_unsecure) + set(_GRPC_GRPCPP gRPC::grpc++) if(CMAKE_CROSSCOMPILING) find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) else() @@ -155,6 +155,6 @@ foreach(_target ${hw_grpc_srcs}) target_link_libraries(${_target} ${_REFLECTION} - ${_GRPC_GRPCPP_UNSECURE} + ${_GRPC_GRPCPP} ${_PROTOBUF_LIBPROTOBUF}) endforeach() diff --git a/examples/python/xds/README.md b/examples/python/xds/README.md new file mode 100644 index 00000000000..bf7809e814d --- /dev/null +++ b/examples/python/xds/README.md @@ -0,0 +1,68 @@ +gRPC Hostname Example +===================== + +The hostname example is a Hello World server whose response includes its +hostname. It also supports health and reflection services. This makes it a good +server to test infrastructure, like load balancing. + +The example requires grpc to already be built. You are strongly encouraged +to check out a git release tag, since there will already be a build of gRPC +available. + +### Run the example + +1. Navigate to this directory: + +```sh +cd grpc/examples/python/xds +``` + +2. Run the server + +```sh +virtualenv venv -p python3 +source venv/bin/activate +pip install -r requirements.txt +python server.py +``` + +3. Verify the Server + +This step is not strictly necessary, but you can use it as a sanity check if +you'd like. If you don't have it, install +[`grpcurl`](https://github.com/fullstorydev/grpcurl/releases). This will allow +you to manually test the service. + +Exercise your server's application-layer service: + +```sh +> grpcurl --plaintext -d '{"name": "you"}' localhost:50051 +{ + "message": "Hello you from rbell.svl.corp.google.com!" +} +``` + +Make sure that all of your server's services are available via reflection: + +```sh +> grpcurl --plaintext localhost:50051 list +grpc.health.v1.Health +grpc.reflection.v1alpha.ServerReflection +helloworld.Greeter +``` + +Make sure that your services are reporting healthy: + +```sh +> grpcurl --plaintext -d '{"service": "helloworld.Greeter"}' localhost:50051 +grpc.health.v1.Health/Check +{ + "status": "SERVING" +} + +> grpcurl --plaintext -d '{"service": ""}' localhost:50051 +grpc.health.v1.Health/Check +{ + "status": "SERVING" +} +``` diff --git a/examples/python/xds/helloworld_pb2.py b/examples/python/xds/helloworld_pb2.py new file mode 100644 index 00000000000..e18ab9acc7a --- /dev/null +++ b/examples/python/xds/helloworld_pb2.py @@ -0,0 +1,134 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto + +import sys +_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor.FileDescriptor( + name='helloworld.proto', + package='helloworld', + syntax='proto3', + serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') +) + + + + +_HELLOREQUEST = _descriptor.Descriptor( + name='HelloRequest', + full_name='helloworld.HelloRequest', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='helloworld.HelloRequest.name', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=32, + serialized_end=60, +) + + +_HELLOREPLY = _descriptor.Descriptor( + name='HelloReply', + full_name='helloworld.HelloReply', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='message', full_name='helloworld.HelloReply.message', index=0, + number=1, type=9, cpp_type=9, label=1, + has_default_value=False, default_value=_b("").decode('utf-8'), + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + ], + extensions=[ + ], + nested_types=[], + enum_types=[ + ], + options=None, + is_extendable=False, + syntax='proto3', + extension_ranges=[], + oneofs=[ + ], + serialized_start=62, + serialized_end=91, +) + +DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST +DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + +HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict( + DESCRIPTOR = _HELLOREQUEST, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloRequest) + )) +_sym_db.RegisterMessage(HelloRequest) + +HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict( + DESCRIPTOR = _HELLOREPLY, + __module__ = 'helloworld_pb2' + # @@protoc_insertion_point(class_scope:helloworld.HelloReply) + )) +_sym_db.RegisterMessage(HelloReply) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW')) + +_GREETER = _descriptor.ServiceDescriptor( + name='Greeter', + full_name='helloworld.Greeter', + file=DESCRIPTOR, + index=0, + options=None, + serialized_start=93, + serialized_end=166, + methods=[ + _descriptor.MethodDescriptor( + name='SayHello', + full_name='helloworld.Greeter.SayHello', + index=0, + containing_service=None, + input_type=_HELLOREQUEST, + output_type=_HELLOREPLY, + options=None, + ), +]) +_sym_db.RegisterServiceDescriptor(_GREETER) + +DESCRIPTOR.services_by_name['Greeter'] = _GREETER + +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/xds/helloworld_pb2_grpc.py b/examples/python/xds/helloworld_pb2_grpc.py new file mode 100644 index 00000000000..18e07d16797 --- /dev/null +++ b/examples/python/xds/helloworld_pb2_grpc.py @@ -0,0 +1,46 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +import grpc + +import helloworld_pb2 as helloworld__pb2 + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) diff --git a/examples/python/xds/requirements.txt b/examples/python/xds/requirements.txt new file mode 100644 index 00000000000..a7ac2e7c8b3 --- /dev/null +++ b/examples/python/xds/requirements.txt @@ -0,0 +1,5 @@ +grpcio>=1.28.0 +protobuf +grpcio-reflection +grpcio-health-checking + diff --git a/examples/python/xds/server.py b/examples/python/xds/server.py new file mode 100644 index 00000000000..75043857f3b --- /dev/null +++ b/examples/python/xds/server.py @@ -0,0 +1,94 @@ +# Copyright 2020 The 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. +"""The Python implementation of the GRPC helloworld.Greeter server.""" + +from concurrent import futures +import argparse +import logging +import multiprocessing +import socket + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + +from grpc_reflection.v1alpha import reflection +from grpc_health.v1 import health +from grpc_health.v1 import health_pb2 +from grpc_health.v1 import health_pb2_grpc + +_DESCRIPTION = "A general purpose dummy server." + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def __init__(self, hostname: str): + self._hostname = hostname if hostname else socket.gethostname() + + def SayHello(self, request: helloworld_pb2.HelloRequest, + context: grpc.ServicerContext) -> helloworld_pb2.HelloReply: + return helloworld_pb2.HelloReply( + message=f"Hello {request.name} from {self._hostname}!") + + +def serve(port: int, hostname: str): + server = grpc.server( + futures.ThreadPoolExecutor(max_workers=multiprocessing.cpu_count())) + + # Add the application servicer to the server. + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(hostname), server) + + # Create a health check servicer. We use the non-blocking implementation + # to avoid thread starvation. + health_servicer = health.HealthServicer( + experimental_non_blocking=True, + experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1)) + health_pb2_grpc.add_HealthServicer_to_server(health_servicer, server) + + # Create a tuple of all of the services we want to export via reflection. + services = tuple( + service.full_name + for service in helloworld_pb2.DESCRIPTOR.services_by_name.values()) + ( + reflection.SERVICE_NAME, health.SERVICE_NAME) + + # Add the reflection service to the server. + reflection.enable_server_reflection(services, server) + server.add_insecure_port(f"[::]:{port}") + server.start() + + # Mark all services as healthy. + overall_server_health = "" + for service in services + (overall_server_health,): + health_servicer.set(service, health_pb2.HealthCheckResponse.SERVING) + + # Park the main application thread. + server.wait_for_termination() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=_DESCRIPTION) + parser.add_argument("port", + default=50051, + type=int, + nargs="?", + help="The port on which to listen.") + parser.add_argument("hostname", + type=str, + default=None, + nargs="?", + help="The name clients will see in responses.") + args = parser.parse_args() + logging.basicConfig() + serve(args.port, args.hostname) diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 8315e96f6ad..c8b176b23ea 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -236,6 +236,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', @@ -685,6 +686,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index f87d5f4603a..d140b005d7f 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -212,6 +212,8 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', @@ -1033,6 +1035,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', diff --git a/grpc.gemspec b/grpc.gemspec index cf0b389f50a..c9a1a8835fd 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -134,6 +134,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc ) diff --git a/grpc.gyp b/grpc.gyp index c32c0dca814..b065ee6f2af 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -445,6 +445,7 @@ 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', @@ -934,6 +935,7 @@ 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 3d291c5e2d1..e910b86596b 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -714,6 +714,10 @@ GRPCAPI grpc_server_credentials* grpc_local_server_credentials_create( /** --- TLS channel/server credentials --- * It is used for experimental purpose for now and subject to change. */ +/** Struct for indicating errors. It is used for + * experimental purpose for now and subject to change. */ +typedef struct grpc_tls_error_details grpc_tls_error_details; + /** Config for TLS key materials. It is used for * experimental purpose for now and subject to change. */ typedef struct grpc_tls_key_materials_config grpc_tls_key_materials_config; @@ -857,7 +861,7 @@ struct grpc_tls_credential_reload_arg { void* cb_user_data; grpc_tls_key_materials_config* key_materials_config; grpc_ssl_certificate_config_reload_status status; - const char* error_details; + grpc_tls_error_details* error_details; grpc_tls_credential_reload_config* config; void* context; void (*destroy_context)(void* ctx); @@ -935,7 +939,7 @@ struct grpc_tls_server_authorization_check_arg { const char* peer_cert; const char* peer_cert_full_chain; grpc_status_code status; - const char* error_details; + grpc_tls_error_details* error_details; grpc_tls_server_authorization_check_config* config; void* context; void (*destroy_context)(void* ctx); diff --git a/include/grpcpp/impl/codegen/client_callback_impl.h b/include/grpcpp/impl/codegen/client_callback_impl.h index fac67c5f49b..83b183e4a5b 100644 --- a/include/grpcpp/impl/codegen/client_callback_impl.h +++ b/include/grpcpp/impl/codegen/client_callback_impl.h @@ -272,7 +272,10 @@ class ClientBidiReactor { void RemoveHold() { stream_->RemoveHold(); } /// Notifies the application that all operations associated with this RPC - /// have completed and provides the RPC status outcome. + /// have completed and all Holds have been removed. OnDone provides the RPC + /// status outcome for both successful and failed RPCs and will be called in + /// all cases. If it is not called, it indicates an application-level problem + /// (like failure to remove a hold). /// /// \param[in] s The status outcome of this RPC virtual void OnDone(const ::grpc::Status& /*s*/) {} @@ -283,19 +286,21 @@ class ClientBidiReactor { /// call of OnReadDone or OnDone. /// /// \param[in] ok Was the initial metadata read successfully? If false, no - /// new read/write operation will succeed. + /// new read/write operation will succeed, and any further + /// Start* operations should not be called. virtual void OnReadInitialMetadataDone(bool /*ok*/) {} /// Notifies the application that a StartRead operation completed. /// /// \param[in] ok Was it successful? If false, no new read/write operation - /// will succeed. + /// will succeed, and any further Start* should not be called. virtual void OnReadDone(bool /*ok*/) {} - /// Notifies the application that a StartWrite operation completed. + /// Notifies the application that a StartWrite or StartWriteLast operation + /// completed. /// /// \param[in] ok Was it successful? If false, no new read/write operation - /// will succeed. + /// will succeed, and any further Start* should not be called. virtual void OnWriteDone(bool /*ok*/) {} /// Notifies the application that a StartWritesDone operation completed. Note @@ -303,7 +308,8 @@ class ClientBidiReactor { /// those that are implicitly invoked as part of a StartWriteLast. /// /// \param[in] ok Was it successful? If false, the application will later see - /// the failure reflected as a bad status in OnDone. + /// the failure reflected as a bad status in OnDone and no + /// further Start* should be called. virtual void OnWritesDoneDone(bool /*ok*/) {} private: diff --git a/include/grpcpp/impl/codegen/method_handler_impl.h b/include/grpcpp/impl/codegen/method_handler_impl.h index 6368b63e1ab..2de193457a1 100644 --- a/include/grpcpp/impl/codegen/method_handler_impl.h +++ b/include/grpcpp/impl/codegen/method_handler_impl.h @@ -303,10 +303,13 @@ class BidiStreamingHandler ::grpc_impl::ServerReaderWriter*)> func, ServiceType* service) + // TODO(vjpai): When gRPC supports C++14, move-capture func in the below : TemplatedBidiStreamingHandler< ::grpc_impl::ServerReaderWriter, false>( - std::bind(func, service, std::placeholders::_1, - std::placeholders::_2)) {} + [func, service]( + ::grpc_impl::ServerContext* ctx, + ::grpc_impl::ServerReaderWriter* + streamer) { return func(service, ctx, streamer); }) {} }; template @@ -321,7 +324,7 @@ class StreamedUnaryHandler func) : TemplatedBidiStreamingHandler< ::grpc_impl::ServerUnaryStreamer, true>( - func) {} + std::move(func)) {} }; template @@ -336,7 +339,7 @@ class SplitServerStreamingHandler func) : TemplatedBidiStreamingHandler< ::grpc_impl::ServerSplitStreamer, false>( - func) {} + std::move(func)) {} }; /// General method handler class for errors that prevent real method use diff --git a/include/grpcpp/impl/codegen/sync_stream_impl.h b/include/grpcpp/impl/codegen/sync_stream_impl.h index 80b0bd73d2a..1a67467ebbc 100644 --- a/include/grpcpp/impl/codegen/sync_stream_impl.h +++ b/include/grpcpp/impl/codegen/sync_stream_impl.h @@ -419,7 +419,7 @@ class ClientReaderWriterInterface : public internal::ClientStreamingInterface, virtual void WaitForInitialMetadata() = 0; /// Half close writing from the client. (signal that the stream of messages - /// coming from the clinet is complete). + /// coming from the client is complete). /// Blocks until currently-pending writes are completed. /// Thread-safe with respect to \a ReaderInterface::Read /// diff --git a/package.xml b/package.xml index d9d5d1516d8..32930b6f65c 100644 --- a/package.xml +++ b/package.xml @@ -114,6 +114,8 @@ + + diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 882e3d60c67..21cf1d69ea7 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -1343,11 +1343,14 @@ void PrintHeaderServerMethodStreamedUnary( printer->Print(*vars, "WithStreamedUnaryMethod_$Method$() {\n" " ::grpc::Service::MarkMethodStreamed($Idx$,\n" - " new ::grpc::internal::StreamedUnaryHandler< $Request$, " - "$Response$>(std::bind" - "(&WithStreamedUnaryMethod_$Method$::" - "Streamed$Method$, this, std::placeholders::_1, " - "std::placeholders::_2)));\n" + " new ::grpc::internal::StreamedUnaryHandler<\n" + " $Request$, $Response$>(\n" + " [this](::grpc_impl::ServerContext* context,\n" + " ::grpc_impl::ServerUnaryStreamer<\n" + " $Request$, $Response$>* streamer) {\n" + " return this->Streamed$Method$(context,\n" + " streamer);\n" + " }));\n" "}\n"); printer->Print(*vars, "~WithStreamedUnaryMethod_$Method$() override {\n" @@ -1391,16 +1394,18 @@ void PrintHeaderServerMethodSplitStreaming( "{}\n"); printer->Print(" public:\n"); printer->Indent(); - printer->Print( - *vars, - "WithSplitStreamingMethod_$Method$() {\n" - " ::grpc::Service::MarkMethodStreamed($Idx$,\n" - " new ::grpc::internal::SplitServerStreamingHandler< $Request$, " - "$Response$>(std::bind" - "(&WithSplitStreamingMethod_$Method$::" - "Streamed$Method$, this, std::placeholders::_1, " - "std::placeholders::_2)));\n" - "}\n"); + printer->Print(*vars, + "WithSplitStreamingMethod_$Method$() {\n" + " ::grpc::Service::MarkMethodStreamed($Idx$,\n" + " new ::grpc::internal::SplitServerStreamingHandler<\n" + " $Request$, $Response$>(\n" + " [this](::grpc_impl::ServerContext* context,\n" + " ::grpc_impl::ServerSplitStreamer<\n" + " $Request$, $Response$>* streamer) {\n" + " return this->Streamed$Method$(context,\n" + " streamer);\n" + " }));\n" + "}\n"); printer->Print(*vars, "~WithSplitStreamingMethod_$Method$() override {\n" " BaseClassMustBeDerivedFromService(this);\n" @@ -2251,7 +2256,12 @@ void PrintSourceService(grpc_generator::Printer* printer, " new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, " "$Request$, " "$Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); + " []($ns$$Service$::Service* service,\n" + " ::grpc_impl::ServerContext* ctx,\n" + " const $Request$* req,\n" + " $Response$* resp) {\n" + " return service->$Method$(ctx, req, resp);\n" + " }, this)));\n"); } else if (ClientOnlyStreaming(method.get())) { printer->Print( *vars, @@ -2260,7 +2270,12 @@ void PrintSourceService(grpc_generator::Printer* printer, " ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n" " new ::grpc::internal::ClientStreamingHandler< " "$ns$$Service$::Service, $Request$, $Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); + " []($ns$$Service$::Service* service,\n" + " ::grpc_impl::ServerContext* ctx,\n" + " ::grpc_impl::ServerReader<$Request$>* reader,\n" + " $Response$* resp) {\n" + " return service->$Method$(ctx, reader, resp);\n" + " }, this)));\n"); } else if (ServerOnlyStreaming(method.get())) { printer->Print( *vars, @@ -2269,16 +2284,25 @@ void PrintSourceService(grpc_generator::Printer* printer, " ::grpc::internal::RpcMethod::SERVER_STREAMING,\n" " new ::grpc::internal::ServerStreamingHandler< " "$ns$$Service$::Service, $Request$, $Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); + " []($ns$$Service$::Service* service,\n" + " ::grpc_impl::ServerContext* ctx,\n" + " const $Request$* req,\n" + " ::grpc_impl::ServerWriter<$Response$>* writer) {\n" + " return service->$Method$(ctx, req, writer);\n" + " }, this)));\n"); } else if (method->BidiStreaming()) { - printer->Print( - *vars, - "AddMethod(new ::grpc::internal::RpcServiceMethod(\n" - " $prefix$$Service$_method_names[$Idx$],\n" - " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n" - " new ::grpc::internal::BidiStreamingHandler< " - "$ns$$Service$::Service, $Request$, $Response$>(\n" - " std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n"); + printer->Print(*vars, + "AddMethod(new ::grpc::internal::RpcServiceMethod(\n" + " $prefix$$Service$_method_names[$Idx$],\n" + " ::grpc::internal::RpcMethod::BIDI_STREAMING,\n" + " new ::grpc::internal::BidiStreamingHandler< " + "$ns$$Service$::Service, $Request$, $Response$>(\n" + " []($ns$$Service$::Service* service,\n" + " ::grpc_impl::ServerContext* ctx,\n" + " ::grpc_impl::ServerReaderWriter<$Response$,\n" + " $Request$>* stream) {\n" + " return service->$Method$(ctx, stream);\n" + " }, this)));\n"); } } printer->Outdent(); diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index a815e1933a6..7dafecc59ba 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -1630,32 +1630,13 @@ void ChannelData::ProcessLbPolicy( // If not, try the setting from channel args. const char* policy_name = nullptr; if (parsed_service_config != nullptr && - parsed_service_config->parsed_deprecated_lb_policy() != nullptr) { - policy_name = parsed_service_config->parsed_deprecated_lb_policy(); + !parsed_service_config->parsed_deprecated_lb_policy().empty()) { + policy_name = parsed_service_config->parsed_deprecated_lb_policy().c_str(); } else { const grpc_arg* channel_arg = grpc_channel_args_find(resolver_result.args, GRPC_ARG_LB_POLICY_NAME); policy_name = grpc_channel_arg_get_string(channel_arg); } - // Special case: If at least one balancer address is present, we use - // the grpclb policy, regardless of what the resolver has returned. - bool found_balancer_address = false; - for (size_t i = 0; i < resolver_result.addresses.size(); ++i) { - const ServerAddress& address = resolver_result.addresses[i]; - if (address.IsBalancer()) { - found_balancer_address = true; - break; - } - } - if (found_balancer_address) { - if (policy_name != nullptr && strcmp(policy_name, "grpclb") != 0) { - gpr_log(GPR_INFO, - "resolver requested LB policy %s but provided at least one " - "balancer address -- forcing use of grpclb LB policy", - policy_name); - } - policy_name = "grpclb"; - } // Use pick_first if nothing was specified and we didn't select grpclb // above. if (policy_name == nullptr) policy_name = "pick_first"; @@ -3975,8 +3956,10 @@ bool CallData::PickSubchannelLocked(grpc_call_element* elem, if (pick_queued_) RemoveCallFromQueuedPicksLocked(elem); // Handle drops. if (GPR_UNLIKELY(result.subchannel == nullptr)) { - result.error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Call dropped by load balancing policy"); + result.error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Call dropped by load balancing policy"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); } else { // Grab a ref to the connected subchannel while we're still // holding the data plane mutex. diff --git a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc index 14b26404b44..1ed5a6993c6 100644 --- a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +++ b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc @@ -16,6 +16,8 @@ #include +#include + #include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h" #include "absl/strings/str_cat.h" @@ -138,8 +140,6 @@ void ChildPolicyHandler::ShutdownLocked() { } void ChildPolicyHandler::UpdateLocked(UpdateArgs args) { - // The name of the policy that this update wants us to use. - const char* child_policy_name = args.config->name(); // If the child policy name changes, we need to create a new child // policy. When this happens, we leave child_policy_ as-is and store // the new child policy in pending_child_policy_. Once the new child @@ -166,10 +166,10 @@ void ChildPolicyHandler::UpdateLocked(UpdateArgs args) { // previous update that changed the policy name, or we have already // finished swapping in the new policy; in this case, child_policy_ // is non-null but pending_child_policy_ is null). In this case: - // a. If child_policy_->name() equals child_policy_name, then we - // update the existing child policy. - // b. If child_policy_->name() does not equal child_policy_name, - // we create a new policy. The policy will be stored in + // a. If going from the current config to the new config does not + // require a new policy, then we update the existing child policy. + // b. If going from the current config to the new config does require a + // new policy, we create a new policy. The policy will be stored in // pending_child_policy_ and will later be swapped into // child_policy_ by the helper when the new child transitions // into state READY. @@ -180,10 +180,11 @@ void ChildPolicyHandler::UpdateLocked(UpdateArgs args) { // not yet transitioned into state READY and been swapped into // child_policy_; in this case, both child_policy_ and // pending_child_policy_ are non-null). In this case: - // a. If pending_child_policy_->name() equals child_policy_name, - // then we update the existing pending child policy. - // b. If pending_child_policy->name() does not equal - // child_policy_name, then we create a new policy. The new + // a. If going from the current config to the new config does not + // require a new policy, then we update the existing pending + // child policy. + // b. If going from the current config to the new config does require a + // new child policy, then we create a new policy. The new // policy is stored in pending_child_policy_ (replacing the one // that was there before, which will be immediately shut down) // and will later be swapped into child_policy_ by the helper @@ -191,12 +192,10 @@ void ChildPolicyHandler::UpdateLocked(UpdateArgs args) { const bool create_policy = // case 1 child_policy_ == nullptr || - // case 2b - (pending_child_policy_ == nullptr && - strcmp(child_policy_->name(), child_policy_name) != 0) || - // case 3b - (pending_child_policy_ != nullptr && - strcmp(pending_child_policy_->name(), child_policy_name) != 0); + // cases 2b and 3b + ConfigChangeRequiresNewPolicyInstance(current_config_.get(), + args.config.get()); + current_config_ = args.config; LoadBalancingPolicy* policy_to_update = nullptr; if (create_policy) { // Cases 1, 2b, and 3b: create a new child policy. @@ -205,11 +204,11 @@ void ChildPolicyHandler::UpdateLocked(UpdateArgs args) { if (GRPC_TRACE_FLAG_ENABLED(*tracer_)) { gpr_log(GPR_INFO, "[child_policy_handler %p] creating new %schild policy %s", this, - child_policy_ == nullptr ? "" : "pending ", child_policy_name); + child_policy_ == nullptr ? "" : "pending ", args.config->name()); } auto& lb_policy = child_policy_ == nullptr ? child_policy_ : pending_child_policy_; - lb_policy = CreateChildPolicy(child_policy_name, *args.args); + lb_policy = CreateChildPolicy(args.config->name(), *args.args); policy_to_update = lb_policy.get(); } else { // Cases 2a and 3a: update an existing policy. @@ -257,8 +256,7 @@ OrphanablePtr ChildPolicyHandler::CreateChildPolicy( std::unique_ptr(helper); lb_policy_args.args = &args; OrphanablePtr lb_policy = - LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( - child_policy_name, std::move(lb_policy_args)); + CreateLoadBalancingPolicy(child_policy_name, std::move(lb_policy_args)); if (GPR_UNLIKELY(lb_policy == nullptr)) { gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", child_policy_name); return nullptr; @@ -277,4 +275,17 @@ OrphanablePtr ChildPolicyHandler::CreateChildPolicy( return lb_policy; } +bool ChildPolicyHandler::ConfigChangeRequiresNewPolicyInstance( + LoadBalancingPolicy::Config* old_config, + LoadBalancingPolicy::Config* new_config) const { + return strcmp(old_config->name(), new_config->name()) != 0; +} + +OrphanablePtr +ChildPolicyHandler::CreateLoadBalancingPolicy( + const char* name, LoadBalancingPolicy::Args args) const { + return LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy( + name, std::move(args)); +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h index 7a32722d367..d67f3264a87 100644 --- a/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +++ b/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h @@ -42,6 +42,18 @@ class ChildPolicyHandler : public LoadBalancingPolicy { void ExitIdleLocked() override; void ResetBackoffLocked() override; + // Returns true if transitioning from the old config to the new config + // requires instantiating a new policy object. + virtual bool ConfigChangeRequiresNewPolicyInstance( + LoadBalancingPolicy::Config* old_config, + LoadBalancingPolicy::Config* new_config) const; + + // Instantiates a new policy of the specified name. + // May be overridden by subclasses to avoid recursion when an LB + // policy factory returns a ChildPolicyHandler. + virtual OrphanablePtr CreateLoadBalancingPolicy( + const char* name, LoadBalancingPolicy::Args args) const; + private: class Helper; @@ -55,6 +67,11 @@ class ChildPolicyHandler : public LoadBalancingPolicy { bool shutting_down_ = false; + // The most recent config passed to UpdateLocked(). + // If pending_child_policy_ is non-null, this is the config passed to + // pending_child_policy_; otherwise, it's the config passed to child_policy_. + RefCountedPtr current_config_; + // Child LB policy. OrphanablePtr child_policy_; OrphanablePtr pending_child_policy_; diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 670c4ffdd56..da72451d549 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -74,6 +74,7 @@ #include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" #include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" @@ -1241,25 +1242,11 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked( // helper code for creating balancer channel // -ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) { - ServerAddressList balancer_addresses; - for (size_t i = 0; i < addresses.size(); ++i) { - if (addresses[i].IsBalancer()) { - // Strip out the is_balancer channel arg, since we don't want to - // recursively use the grpclb policy in the channel used to talk to - // the balancers. Note that we do NOT strip out the balancer_name - // channel arg, since we need that to set the authority correctly - // to talk to the balancers. - static const char* args_to_remove[] = { - GRPC_ARG_ADDRESS_IS_BALANCER, - }; - balancer_addresses.emplace_back( - addresses[i].address(), - grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove, - GPR_ARRAY_SIZE(args_to_remove))); - } - } - return balancer_addresses; +ServerAddressList ExtractBalancerAddresses(const grpc_channel_args& args) { + const ServerAddressList* addresses = + FindGrpclbBalancerAddressesInChannelArgs(args); + if (addresses != nullptr) return *addresses; + return ServerAddressList(); } /* Returns the channel args for the LB channel, used to create a bidirectional @@ -1452,27 +1439,25 @@ void GrpcLb::UpdateLocked(UpdateArgs args) { // helpers for UpdateLocked() // -// Returns the backend addresses extracted from the given addresses. -ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) { +ServerAddressList AddNullLbTokenToAddresses( + const ServerAddressList& addresses) { static const char* lb_token = ""; grpc_arg arg = grpc_channel_arg_pointer_create( const_cast(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), const_cast(lb_token), &lb_token_arg_vtable); - ServerAddressList backend_addresses; + ServerAddressList addresses_out; for (size_t i = 0; i < addresses.size(); ++i) { - if (!addresses[i].IsBalancer()) { - backend_addresses.emplace_back( - addresses[i].address(), - grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); - } + addresses_out.emplace_back( + addresses[i].address(), + grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1)); } - return backend_addresses; + return addresses_out; } void GrpcLb::ProcessAddressesAndChannelArgsLocked( const ServerAddressList& addresses, const grpc_channel_args& args) { // Update fallback address list. - fallback_backend_addresses_ = ExtractBackendAddresses(addresses); + fallback_backend_addresses_ = AddNullLbTokenToAddresses(addresses); // Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args, // since we use this to trigger the client_load_reporting filter. static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME}; @@ -1482,7 +1467,7 @@ void GrpcLb::ProcessAddressesAndChannelArgsLocked( args_ = grpc_channel_args_copy_and_add_and_remove( &args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1); // Construct args for balancer channel. - ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses); + ServerAddressList balancer_addresses = ExtractBalancerAddresses(args); grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs( balancer_addresses, response_generator_.get(), &args); // Create balancer channel if needed. diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc new file mode 100644 index 00000000000..2888c3b94ae --- /dev/null +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc @@ -0,0 +1,89 @@ +// +// Copyright 2019 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 + +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/useful.h" + +// Channel arg key for the list of balancer addresses. +#define GRPC_ARG_GRPCLB_BALANCER_ADDRESSES "grpc.grpclb_balancer_addresses" +// Channel arg key for a string indicating an address's balancer name. +#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name" + +namespace grpc_core { + +namespace { + +void* BalancerAddressesArgCopy(void* p) { + ServerAddressList* address_list = static_cast(p); + return new ServerAddressList(*address_list); +} + +void BalancerAddressesArgDestroy(void* p) { + ServerAddressList* address_list = static_cast(p); + delete address_list; +} + +int BalancerAddressesArgCmp(void* p, void* q) { + ServerAddressList* address_list1 = static_cast(p); + ServerAddressList* address_list2 = static_cast(q); + if (address_list1 == nullptr || address_list2 == nullptr) { + return GPR_ICMP(address_list1, address_list2); + } + if (address_list1->size() > address_list2->size()) return 1; + if (address_list1->size() < address_list2->size()) return -1; + for (size_t i = 0; i < address_list1->size(); ++i) { + int retval = (*address_list1)[i].Cmp((*address_list2)[i]); + if (retval != 0) return retval; + } + return 0; +} + +const grpc_arg_pointer_vtable kBalancerAddressesArgVtable = { + BalancerAddressesArgCopy, BalancerAddressesArgDestroy, + BalancerAddressesArgCmp}; + +} // namespace + +grpc_arg CreateGrpclbBalancerAddressesArg( + const ServerAddressList* address_list) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_GRPCLB_BALANCER_ADDRESSES), + const_cast(address_list), + &kBalancerAddressesArgVtable); +} + +const ServerAddressList* FindGrpclbBalancerAddressesInChannelArgs( + const grpc_channel_args& args) { + return grpc_channel_args_find_pointer( + &args, const_cast(GRPC_ARG_GRPCLB_BALANCER_ADDRESSES)); +} + +grpc_arg CreateGrpclbBalancerNameArg(const char* balancer_name) { + return grpc_channel_arg_string_create( + const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), + const_cast(balancer_name)); +} + +const char* FindGrpclbBalancerNameInChannelArgs(const grpc_channel_args& args) { + return grpc_channel_args_find_string( + &args, const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME)); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h new file mode 100644 index 00000000000..9b6b259deca --- /dev/null +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h @@ -0,0 +1,40 @@ +// +// Copyright 2019 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_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_BALANCER_ADDRESSES_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_BALANCER_ADDRESSES_H + +#include + +#include + +#include "src/core/ext/filters/client_channel/server_address.h" + +namespace grpc_core { + +grpc_arg CreateGrpclbBalancerAddressesArg( + const ServerAddressList* address_list); +const ServerAddressList* FindGrpclbBalancerAddressesInChannelArgs( + const grpc_channel_args& args); + +grpc_arg CreateGrpclbBalancerNameArg(const char* balancer_name); +const char* FindGrpclbBalancerNameInChannelArgs(const grpc_channel_args& args); + +} // namespace grpc_core + +#endif /* \ +GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_GRPCLB_GRPCLB_BALANCER_ADDRESSES_H \ + */ diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc index 5bc4f5157ad..414f8274317 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc @@ -27,6 +27,7 @@ #include #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" @@ -55,8 +56,8 @@ RefCountedPtr CreateTargetAuthorityTable( grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0); target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str); gpr_free(addr_str); - char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find( - addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME)); + const char* balancer_name = + FindGrpclbBalancerNameInChannelArgs(*addresses[i].args()); target_authority_entries[i].value.reset(gpr_strdup(balancer_name)); } RefCountedPtr target_authority_table = diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index 4932a6869f1..2d8988926e4 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -370,13 +370,6 @@ SubchannelList::SubchannelList( GRPC_ARG_SERVICE_CONFIG}; // Create a subchannel for each address. for (size_t i = 0; i < addresses.size(); i++) { - // TODO(roth): we should ideally hide this from the LB policy code. In - // principle, if we're dealing with this special case in the client_channel - // code for selecting grpclb, then we should also strip out these addresses - // there if we're not using grpclb. - if (addresses[i].IsBalancer()) { - continue; - } InlinedVector args_to_add; const size_t subchannel_address_arg_index = args_to_add.size(); args_to_add.emplace_back( diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index a9205b5f4e0..9196bf628ca 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -25,6 +25,8 @@ #include #include +#include "absl/types/optional.h" + #include #include #include @@ -80,7 +82,7 @@ class XdsConfig : public LoadBalancingPolicy::Config { XdsConfig(RefCountedPtr child_policy, RefCountedPtr fallback_policy, std::string eds_service_name, - Optional lrs_load_reporting_server_name) + absl::optional lrs_load_reporting_server_name) : child_policy_(std::move(child_policy)), fallback_policy_(std::move(fallback_policy)), eds_service_name_(std::move(eds_service_name)), @@ -101,7 +103,7 @@ class XdsConfig : public LoadBalancingPolicy::Config { return eds_service_name_.empty() ? nullptr : eds_service_name_.c_str(); }; - const Optional& lrs_load_reporting_server_name() const { + const absl::optional& lrs_load_reporting_server_name() const { return lrs_load_reporting_server_name_; }; @@ -109,7 +111,7 @@ class XdsConfig : public LoadBalancingPolicy::Config { RefCountedPtr child_policy_; RefCountedPtr fallback_policy_; std::string eds_service_name_; - Optional lrs_load_reporting_server_name_; + absl::optional lrs_load_reporting_server_name_; }; class XdsLb : public LoadBalancingPolicy { @@ -494,6 +496,16 @@ XdsLb::PickResult XdsLb::LocalityPicker::Pick(PickArgs args) { result.type = PickResult::PICK_COMPLETE; return result; } + // If we didn't drop, we better have some localities to pick from. + if (pickers_.empty()) { // Should never happen. + PickResult result; + result.type = PickResult::PICK_FAILED; + result.error = + grpc_error_set_int(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "xds picker not given any localities"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL); + return result; + } // Generate a random number in [0, total weight). const uint32_t key = rand() % pickers_[pickers_.size() - 1].first; // Forward pick to whichever locality maps to the range in which the @@ -568,7 +580,7 @@ class XdsLb::EndpointWatcher : public XdsClient::EndpointWatcherInterface { } // If the balancer tells us to drop all the calls, we should exit fallback // mode immediately. - if (update.drop_all) xds_policy_->MaybeExitFallbackMode(); + if (update.drop_config->drop_all()) xds_policy_->MaybeExitFallbackMode(); // Update the drop config. const bool drop_config_changed = xds_policy_->drop_config_ == nullptr || @@ -723,7 +735,6 @@ void XdsLb::UpdateLocked(UpdateArgs args) { } const bool is_initial_update = args_ == nullptr; // Update config. - const char* old_eds_service_name = eds_service_name(); auto old_config = std::move(config_); config_ = std::move(args.config); // Update fallback address list. @@ -771,30 +782,8 @@ void XdsLb::UpdateLocked(UpdateArgs args) { eds_service_name(), eds_service_name()); } } - // Update priority list. - // Note that this comes after updating drop_stats_, since we want that - // to be used by any new picker we create here. - // No need to do this on the initial update, since there won't be any - // priorities to update yet. - if (!is_initial_update) { - const bool update_locality_stats = - config_->lrs_load_reporting_server_name() != - old_config->lrs_load_reporting_server_name() || - strcmp(old_eds_service_name, eds_service_name()) != 0; - UpdatePrioritiesLocked(update_locality_stats); - } - // Update endpoint watcher if needed. - if (is_initial_update || - strcmp(old_eds_service_name, eds_service_name()) != 0) { - if (!is_initial_update) { - if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { - gpr_log(GPR_INFO, "[xdslb %p] cancelling watch for %s", this, - old_eds_service_name); - } - xds_client()->CancelEndpointDataWatch(StringView(old_eds_service_name), - endpoint_watcher_, - /*delay_unsubscription=*/true); - } + // On the initial update, create the endpoint watcher. + if (is_initial_update) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { gpr_log(GPR_INFO, "[xdslb %p] starting watch for %s", this, eds_service_name()); @@ -804,6 +793,16 @@ void XdsLb::UpdateLocked(UpdateArgs args) { endpoint_watcher_ = watcher.get(); xds_client()->WatchEndpointData(StringView(eds_service_name()), std::move(watcher)); + } else { + // Update priority list. + // Note that this comes after updating drop_stats_, since we want that + // to be used by any new picker we create here. + // No need to do this on the initial update, since there won't be any + // priorities to update yet. + const bool update_locality_stats = + config_->lrs_load_reporting_server_name() != + old_config->lrs_load_reporting_server_name(); + UpdatePrioritiesLocked(update_locality_stats); } } @@ -930,13 +929,24 @@ void XdsLb::UpdatePrioritiesLocked(bool update_locality_stats) { void XdsLb::UpdateXdsPickerLocked() { // If we are in fallback mode, don't generate an xds picker from localities. if (fallback_policy_ != nullptr) return; - if (current_priority_ == UINT32_MAX) { - grpc_error* error = grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("no ready locality map"), - GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + // If we're dropping all calls, report READY, even though we won't + // have a selected priority. + if (drop_config_ != nullptr && drop_config_->drop_all()) { channel_control_helper()->UpdateState( - GRPC_CHANNEL_TRANSIENT_FAILURE, - absl::make_unique(error)); + GRPC_CHANNEL_READY, + absl::make_unique(this, LocalityPicker::PickerList{})); + return; + } + // If we don't have a selected priority, report TRANSIENT_FAILURE. + if (current_priority_ == UINT32_MAX) { + if (fallback_policy_ == nullptr) { + grpc_error* error = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("no ready locality map"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + channel_control_helper()->UpdateState( + GRPC_CHANNEL_TRANSIENT_FAILURE, + absl::make_unique(error)); + } return; } priorities_[current_priority_]->UpdateXdsPickerLocked(); @@ -998,7 +1008,16 @@ OrphanablePtr XdsLb::ExtractLocalityLocked( if (priority == exclude_priority) continue; LocalityMap* locality_map = priorities_[priority].get(); auto locality = locality_map->ExtractLocalityLocked(name); - if (locality != nullptr) return locality; + if (locality != nullptr) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, + "[xdslb %p] moving locality %p %s to new priority (%" PRIu32 + " -> %" PRIu32 ")", + this, locality.get(), name->AsHumanReadableString(), + exclude_priority, priority); + } + return locality; + } } return nullptr; } @@ -1024,7 +1043,7 @@ XdsLb::LocalityMap::LocalityMap(RefCountedPtr xds_policy, &on_failover_timer_); failover_timer_callback_pending_ = true; // This is the first locality map ever created, report CONNECTING. - if (priority_ == 0) { + if (priority_ == 0 && xds_policy_->fallback_policy_ == nullptr) { xds_policy_->channel_control_helper()->UpdateState( GRPC_CHANNEL_CONNECTING, absl::make_unique( @@ -1158,6 +1177,10 @@ XdsLb::LocalityMap::ExtractLocalityLocked( } void XdsLb::LocalityMap::DeactivateLocked() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] deactivating priority %" PRIu32, xds_policy(), + priority_); + } // If already deactivated, don't do it again. if (delayed_removal_timer_callback_pending_) return; MaybeCancelFailoverTimerLocked(); @@ -1182,6 +1205,10 @@ bool XdsLb::LocalityMap::MaybeReactivateLocked() { // Don't reactivate a priority that is not higher than the current one. if (priority_ >= xds_policy_->current_priority_) return false; // Reactivate this priority by cancelling deletion timer. + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] reactivating priority %" PRIu32, xds_policy(), + priority_); + } if (delayed_removal_timer_callback_pending_) { grpc_timer_cancel(&delayed_removal_timer_); } @@ -1438,6 +1465,10 @@ void XdsLb::LocalityMap::Locality::UpdateLocked(uint32_t locality_weight, // Update locality weight. weight_ = locality_weight; if (delayed_removal_timer_callback_pending_) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] Locality %p %s: reactivating", xds_policy(), + this, name_->AsHumanReadableString()); + } grpc_timer_cancel(&delayed_removal_timer_); } // Update locality stats. @@ -1495,6 +1526,10 @@ void XdsLb::LocalityMap::Locality::Orphan() { void XdsLb::LocalityMap::Locality::DeactivateLocked() { // If already deactivated, don't do that again. if (weight_ == 0) return; + if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_trace)) { + gpr_log(GPR_INFO, "[xdslb %p] Locality %p %s: deactivating", xds_policy(), + this, name_->AsHumanReadableString()); + } // Set the locality weight to 0 so that future xds picker won't contain this // locality. weight_ = 0; @@ -1572,7 +1607,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { public: OrphanablePtr CreateLoadBalancingPolicy( LoadBalancingPolicy::Args args) const override { - return MakeOrphanable(std::move(args)); + return MakeOrphanable(std::move(args), &grpc_lb_xds_trace); } const char* name() const override { return kXds; } @@ -1656,7 +1691,7 @@ class XdsFactory : public LoadBalancingPolicyFactory { } } if (error_list.empty()) { - Optional optional_lrs_load_reporting_server_name; + absl::optional optional_lrs_load_reporting_server_name; if (lrs_load_reporting_server_name != nullptr) { optional_lrs_load_reporting_server_name.emplace( std::string(lrs_load_reporting_server_name)); @@ -1670,6 +1705,36 @@ class XdsFactory : public LoadBalancingPolicyFactory { return nullptr; } } + + private: + class XdsChildHandler : public ChildPolicyHandler { + public: + XdsChildHandler(Args args, TraceFlag* tracer) + : ChildPolicyHandler(std::move(args), tracer) {} + + bool ConfigChangeRequiresNewPolicyInstance( + LoadBalancingPolicy::Config* old_config, + LoadBalancingPolicy::Config* new_config) const override { + GPR_ASSERT(old_config->name() == kXds); + GPR_ASSERT(new_config->name() == kXds); + XdsConfig* old_xds_config = static_cast(old_config); + XdsConfig* new_xds_config = static_cast(new_config); + const char* old_eds_service_name = + old_xds_config->eds_service_name() == nullptr + ? "" + : old_xds_config->eds_service_name(); + const char* new_eds_service_name = + new_xds_config->eds_service_name() == nullptr + ? "" + : new_xds_config->eds_service_name(); + return strcmp(old_eds_service_name, new_eds_service_name) != 0; + } + + OrphanablePtr CreateLoadBalancingPolicy( + const char* name, LoadBalancingPolicy::Args args) const override { + return MakeOrphanable(std::move(args)); + } + }; }; } // namespace diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index a8215439d2a..e2a05d03ad3 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -30,6 +30,7 @@ #include #include "src/core/ext/filters/client_channel/http_connect_handshaker.h" +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" #include "src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h" @@ -107,8 +108,10 @@ class AresDnsResolver : public Resolver { grpc_millis last_resolution_timestamp_ = -1; /// retry backoff state BackOff backoff_; - /// currently resolving addresses + /// currently resolving backend addresses std::unique_ptr addresses_; + /// currently resolving balancer addresses + std::unique_ptr balancer_addresses_; /// currently resolving service config char* service_config_json_ = nullptr; // has shutdown been initiated @@ -328,9 +331,11 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { r->Unref(DEBUG_LOCATION, "OnResolvedLocked() shutdown"); return; } - if (r->addresses_ != nullptr) { + if (r->addresses_ != nullptr || r->balancer_addresses_ != nullptr) { Result result; - result.addresses = std::move(*r->addresses_); + if (r->addresses_ != nullptr) { + result.addresses = std::move(*r->addresses_); + } if (r->service_config_json_ != nullptr) { std::string service_config_string = ChooseServiceConfig( r->service_config_json_, &result.service_config_error); @@ -343,9 +348,16 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { service_config_string, &result.service_config_error); } } - result.args = grpc_channel_args_copy(r->channel_args_); + InlinedVector new_args; + if (r->balancer_addresses_ != nullptr) { + new_args.push_back( + CreateGrpclbBalancerAddressesArg(r->balancer_addresses_.get())); + } + result.args = grpc_channel_args_copy_and_add( + r->channel_args_, new_args.data(), new_args.size()); r->result_handler()->ReturnResult(std::move(result)); r->addresses_.reset(); + r->balancer_addresses_.reset(); // Reset backoff state so that we start from the beginning when the // next request gets triggered. r->backoff_.Reset(); @@ -424,7 +436,8 @@ void AresDnsResolver::StartResolvingLocked() { GRPC_CLOSURE_INIT(&on_resolved_, OnResolved, this, grpc_schedule_on_exec_ctx); pending_request_ = grpc_dns_lookup_ares_locked( dns_server_, name_to_resolve_, kDefaultPort, interested_parties_, - &on_resolved_, &addresses_, enable_srv_queries_ /* check_grpclb */, + &on_resolved_, &addresses_, + enable_srv_queries_ ? &balancer_addresses_ : nullptr, request_service_config_ ? &service_config_json_ : nullptr, query_timeout_ms_, combiner()); last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now(); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 761bed9a82d..b9960453ccf 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -33,6 +33,7 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" #include "src/core/lib/gpr/string.h" @@ -60,6 +61,8 @@ struct grpc_ares_request { grpc_closure* on_done; /** the pointer to receive the resolved addresses */ std::unique_ptr* addresses_out; + /** the pointer to receive the resolved balancer addresses */ + std::unique_ptr* balancer_addresses_out; /** the pointer to receive the service config in JSON */ char** service_config_json_out; /** the evernt driver used by this request */ @@ -184,17 +187,17 @@ static void on_hostbyname_done_locked(void* arg, int status, int /*timeouts*/, GRPC_CARES_TRACE_LOG( "request:%p on_hostbyname_done_locked host=%s ARES_SUCCESS", r, hr->host); - if (*r->addresses_out == nullptr) { - *r->addresses_out = absl::make_unique(); + std::unique_ptr* address_list_ptr = + hr->is_balancer ? r->balancer_addresses_out : r->addresses_out; + if (*address_list_ptr == nullptr) { + *address_list_ptr = absl::make_unique(); } - ServerAddressList& addresses = **r->addresses_out; + ServerAddressList& addresses = **address_list_ptr; for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) { - grpc_core::InlinedVector args_to_add; + grpc_core::InlinedVector args_to_add; if (hr->is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host)); + args_to_add.emplace_back( + grpc_core::CreateGrpclbBalancerNameArg(hr->host)); } grpc_channel_args* args = grpc_channel_args_copy_and_add( nullptr, args_to_add.data(), args_to_add.size()); @@ -350,7 +353,7 @@ done: void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_request* r, const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, - bool check_grpclb, int query_timeout_ms, grpc_core::Combiner* combiner) { + int query_timeout_ms, grpc_core::Combiner* combiner) { grpc_error* error = GRPC_ERROR_NONE; grpc_ares_hostbyname_request* hr = nullptr; ares_channel* channel = nullptr; @@ -425,7 +428,7 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( /*is_balancer=*/false); ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked, hr); - if (check_grpclb) { + if (r->balancer_addresses_out != nullptr) { /* Query the SRV record */ grpc_ares_request_ref_locked(r); char* service_name; @@ -588,7 +591,8 @@ static bool grpc_ares_maybe_resolve_localhost_manually_locked( static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addrs, bool check_grpclb, + std::unique_ptr* addrs, + std::unique_ptr* balancer_addrs, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner) { grpc_ares_request* r = @@ -596,6 +600,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( r->ev_driver = nullptr; r->on_done = on_done; r->addresses_out = addrs; + r->balancer_addresses_out = balancer_addrs; r->service_config_json_out = service_config_json; r->error = GRPC_ERROR_NONE; r->pending_queries = 0; @@ -618,20 +623,21 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( // as to cut down on lookups over the network, especially in tests: // https://github.com/grpc/proposal/pull/79 if (target_matches_localhost(name)) { - check_grpclb = false; + r->balancer_addresses_out = nullptr; r->service_config_json_out = nullptr; } // Look up name using c-ares lib. grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( - r, dns_server, name, default_port, interested_parties, check_grpclb, - query_timeout_ms, combiner); + r, dns_server, name, default_port, interested_parties, query_timeout_ms, + combiner); return r; } grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addrs, bool check_grpclb, + std::unique_ptr* addrs, + std::unique_ptr* balancer_addrs, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner) = grpc_dns_lookup_ares_locked_impl; @@ -709,7 +715,6 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { static_cast(gpr_zalloc( sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs)); for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) { - GPR_ASSERT(!(*r->addresses)[i].IsBalancer()); memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(), sizeof(grpc_resolved_address)); } @@ -736,9 +741,9 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( grpc_schedule_on_exec_ctx); r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, - &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */, - nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, - r->combiner); + &r->on_dns_lookup_done_locked, &r->addresses, + nullptr /* balancer_addresses */, nullptr /* service_config_json */, + GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, r->combiner); } static void grpc_resolve_address_ares_impl(const char* name, diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 115018155b3..bfa888ce9f5 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -63,7 +63,8 @@ extern void (*grpc_resolve_address_ares)(const char* name, extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, bool check_grpclb, + std::unique_ptr* addresses, + std::unique_ptr* balancer_addresses, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner); diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index fe631f873e9..be880f6c1c2 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -29,7 +29,8 @@ struct grpc_ares_request { static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addrs, bool check_grpclb, + std::unique_ptr* addrs, + std::unique_ptr* balancer_addrs, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner) { return NULL; @@ -38,7 +39,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addrs, bool check_grpclb, + std::unique_ptr* addrs, + std::unique_ptr* balancer_addrs, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner) = grpc_dns_lookup_ares_locked_impl; diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc index 080ecd354e6..d87890d1c97 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.cc +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc @@ -317,7 +317,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json, GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); std::vector error_list; RefCountedPtr parsed_lb_config; - grpc_core::UniquePtr lb_policy_name; + std::string lb_policy_name; Optional retry_throttling; const char* health_check_service_name = nullptr; // Parse LB config. @@ -340,16 +340,13 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json, error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:type should be string")); } else { - lb_policy_name.reset(gpr_strdup(it->second.string_value().c_str())); - char* lb_policy = lb_policy_name.get(); - if (lb_policy != nullptr) { - for (size_t i = 0; i < strlen(lb_policy); ++i) { - lb_policy[i] = tolower(lb_policy[i]); - } + lb_policy_name = it->second.string_value(); + for (size_t i = 0; i < lb_policy_name.size(); ++i) { + lb_policy_name[i] = tolower(lb_policy_name[i]); } bool requires_config = false; if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists( - lb_policy, &requires_config)) { + lb_policy_name.c_str(), &requires_config)) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:loadBalancingPolicy error:Unknown lb policy")); } else if (requires_config) { @@ -357,7 +354,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const Json& json, gpr_asprintf(&error_msg, "field:loadBalancingPolicy error:%s requires a config. " "Please use loadBalancingConfig instead.", - lb_policy); + lb_policy_name.c_str()); error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg)); gpr_free(error_msg); } diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h index 27d7f6f1396..1f928cfd551 100644 --- a/src/core/ext/filters/client_channel/resolver_result_parsing.h +++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h @@ -46,7 +46,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { ClientChannelGlobalParsedConfig( RefCountedPtr parsed_lb_config, - grpc_core::UniquePtr parsed_deprecated_lb_policy, + std::string parsed_deprecated_lb_policy, const Optional& retry_throttling, const char* health_check_service_name) : parsed_lb_config_(std::move(parsed_lb_config)), @@ -62,8 +62,8 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { return parsed_lb_config_; } - const char* parsed_deprecated_lb_policy() const { - return parsed_deprecated_lb_policy_.get(); + const std::string& parsed_deprecated_lb_policy() const { + return parsed_deprecated_lb_policy_; } const char* health_check_service_name() const { @@ -72,7 +72,7 @@ class ClientChannelGlobalParsedConfig : public ServiceConfig::ParsedConfig { private: RefCountedPtr parsed_lb_config_; - grpc_core::UniquePtr parsed_deprecated_lb_policy_; + std::string parsed_deprecated_lb_policy_; Optional retry_throttling_; const char* health_check_service_name_; }; diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc index d46896b754b..93d361a8154 100644 --- a/src/core/ext/filters/client_channel/server_address.cc +++ b/src/core/ext/filters/client_channel/server_address.cc @@ -37,15 +37,12 @@ ServerAddress::ServerAddress(const void* address, size_t address_len, address_.len = static_cast(address_len); } -bool ServerAddress::operator==(const ServerAddress& other) const { - return address_.len == other.address_.len && - memcmp(address_.addr, other.address_.addr, address_.len) == 0 && - grpc_channel_args_compare(args_, other.args_) == 0; -} - -bool ServerAddress::IsBalancer() const { - return grpc_channel_arg_get_bool( - grpc_channel_args_find(args_, GRPC_ARG_ADDRESS_IS_BALANCER), false); +int ServerAddress::Cmp(const ServerAddress& other) const { + if (address_.len > other.address_.len) return 1; + if (address_.len < other.address_.len) return -1; + int retval = memcmp(address_.addr, other.address_.addr, address_.len); + if (retval != 0) return retval; + return grpc_channel_args_compare(args_, other.args_); } } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/server_address.h b/src/core/ext/filters/client_channel/server_address.h index acd71358810..10f49f2f344 100644 --- a/src/core/ext/filters/client_channel/server_address.h +++ b/src/core/ext/filters/client_channel/server_address.h @@ -25,13 +25,6 @@ #include "src/core/lib/gprpp/inlined_vector.h" #include "src/core/lib/iomgr/resolve_address.h" -// Channel arg key for a bool indicating whether an address is a grpclb -// load balancer (as opposed to a backend). -#define GRPC_ARG_ADDRESS_IS_BALANCER "grpc.address_is_balancer" - -// Channel arg key for a string indicating an address's balancer name. -#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name" - namespace grpc_core { // @@ -73,13 +66,13 @@ class ServerAddress { return *this; } - bool operator==(const ServerAddress& other) const; + bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; } + + int Cmp(const ServerAddress& other) const; const grpc_resolved_address& address() const { return address_; } const grpc_channel_args* args() const { return args_; } - bool IsBalancer() const; - private: grpc_resolved_address address_; grpc_channel_args* args_; diff --git a/src/core/ext/filters/client_channel/service_config.cc b/src/core/ext/filters/client_channel/service_config.cc index 884f68f2090..f08ebe1a37d 100644 --- a/src/core/ext/filters/client_channel/service_config.cc +++ b/src/core/ext/filters/client_channel/service_config.cc @@ -20,6 +20,8 @@ #include +#include "absl/strings/str_cat.h" + #include #include #include @@ -27,9 +29,7 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/json/json.h" -#include "src/core/lib/slice/slice_hash_table.h" #include "src/core/lib/slice/slice_internal.h" -#include "src/core/lib/slice/slice_string_helpers.h" namespace grpc_core { @@ -77,6 +77,12 @@ ServiceConfig::ServiceConfig(std::string json_string, Json json, } } +ServiceConfig::~ServiceConfig() { + for (auto& p : parsed_method_configs_map_) { + grpc_slice_unref_internal(p.first); + } +} + grpc_error* ServiceConfig::ParseGlobalParams() { std::vector error_list; for (size_t i = 0; i < g_registered_parsers->size(); i++) { @@ -91,10 +97,8 @@ grpc_error* ServiceConfig::ParseGlobalParams() { return GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list); } -grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigVectorTable( - const Json& json, - InlinedVector::Entry, 10>* - entries) { +grpc_error* ServiceConfig::ParseJsonMethodConfig(const Json& json) { + // Parse method config with each registered parser. auto objs_vector = absl::make_unique(); InlinedVector error_list; for (size_t i = 0; i < g_registered_parsers->size(); i++) { @@ -108,8 +112,8 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigVectorTable( } parsed_method_config_vectors_storage_.push_back(std::move(objs_vector)); const auto* vector_ptr = parsed_method_config_vectors_storage_.back().get(); - // Construct list of paths. - InlinedVector, 10> paths; + // Add an entry for each path. + bool found_name = false; auto it = json.object_value().find("name"); if (it != json.object_value().end()) { if (it->second.type() != Json::Type::ARRAY) { @@ -120,29 +124,42 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigVectorTable( const Json::Array& name_array = it->second.array_value(); for (const Json& name : name_array) { grpc_error* parse_error = GRPC_ERROR_NONE; - UniquePtr path = ParseJsonMethodName(name, &parse_error); - if (path == nullptr) { + std::string path = ParseJsonMethodName(name, &parse_error); + if (parse_error != GRPC_ERROR_NONE) { error_list.push_back(parse_error); } else { - GPR_DEBUG_ASSERT(parse_error == GRPC_ERROR_NONE); - paths.push_back(std::move(path)); + found_name = true; + if (path.empty()) { + if (default_method_config_vector_ != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:multiple default method configs")); + } + default_method_config_vector_ = vector_ptr; + } else { + grpc_slice key = grpc_slice_from_copied_string(path.c_str()); + // If the key is not already present in the map, this will + // store a ref to the key in the map. + auto& value = parsed_method_configs_map_[key]; + if (value != nullptr) { + error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error:multiple method configs with same name")); + // The map entry already existed, so we need to unref the + // key we just created. + grpc_slice_unref_internal(key); + } else { + value = vector_ptr; + } + } } } } - if (paths.size() == 0) { - error_list.push_back( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("No names specified")); - } - // Add entry for each path. - for (size_t i = 0; i < paths.size(); ++i) { - entries->push_back( - {grpc_slice_from_copied_string(paths[i].get()), vector_ptr}); + if (!found_name) { + parsed_method_config_vectors_storage_.pop_back(); } return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list); } grpc_error* ServiceConfig::ParsePerMethodParams() { - InlinedVector::Entry, 10> entries; std::vector error_list; auto it = json_.object_value().find("methodConfig"); if (it != json_.object_value().end()) { @@ -156,91 +173,80 @@ grpc_error* ServiceConfig::ParsePerMethodParams() { "field:methodConfig error:not of type Object")); continue; } - grpc_error* error = ParseJsonMethodConfigToServiceConfigVectorTable( - method_config, &entries); + grpc_error* error = ParseJsonMethodConfig(method_config); if (error != GRPC_ERROR_NONE) { error_list.push_back(error); } } } - if (!entries.empty()) { - parsed_method_configs_table_ = - SliceHashTable::Create( - entries.size(), entries.data(), nullptr); - } return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list); } -UniquePtr ServiceConfig::ParseJsonMethodName(const Json& json, - grpc_error** error) { +std::string ServiceConfig::ParseJsonMethodName(const Json& json, + grpc_error** error) { if (json.type() != Json::Type::OBJECT) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:name error:type is not object"); - return nullptr; + return ""; } // Find service name. + const std::string* service_name = nullptr; auto it = json.object_value().find("service"); - if (it == json.object_value().end()) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:service error:not found"); - return nullptr; // Required field. - } - if (it->second.type() != Json::Type::STRING) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:service error:not of type string"); - return nullptr; - } - if (it->second.string_value().empty()) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:service error:empty value"); - return nullptr; + if (it != json.object_value().end() && + it->second.type() != Json::Type::JSON_NULL) { + if (it->second.type() != Json::Type::STRING) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "field:name error: field:service error:not of type string"); + return ""; + } + if (!it->second.string_value().empty()) { + service_name = &it->second.string_value(); + } } - const char* service_name = it->second.string_value().c_str(); - const char* method_name = nullptr; + const std::string* method_name = nullptr; // Find method name. it = json.object_value().find("method"); - if (it != json.object_value().end()) { + if (it != json.object_value().end() && + it->second.type() != Json::Type::JSON_NULL) { if (it->second.type() != Json::Type::STRING) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( "field:name error: field:method error:not of type string"); - return nullptr; + return ""; + } + if (!it->second.string_value().empty()) { + method_name = &it->second.string_value(); } - if (it->second.string_value().empty()) { + } + // If neither service nor method are specified, it's the default. + // Method name may not be specified without service name. + if (service_name == nullptr) { + if (method_name != nullptr) { *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:name error: field:method error:empty value"); - return nullptr; + "field:name error:method name populated without service name"); } - method_name = it->second.string_value().c_str(); + return ""; } - char* path; - gpr_asprintf(&path, "/%s/%s", service_name, - method_name == nullptr ? "" : method_name); - return grpc_core::UniquePtr(path); + // Construct path. + return absl::StrCat("/", *service_name, "/", + method_name == nullptr ? "" : *method_name); } const ServiceConfig::ParsedConfigVector* -ServiceConfig::GetMethodParsedConfigVector(const grpc_slice& path) { - if (parsed_method_configs_table_.get() == nullptr) { - return nullptr; - } - const auto* value = parsed_method_configs_table_->Get(path); +ServiceConfig::GetMethodParsedConfigVector(const grpc_slice& path) const { + // Try looking up the full path in the map. + auto it = parsed_method_configs_map_.find(path); + if (it != parsed_method_configs_map_.end()) return it->second; // If we didn't find a match for the path, try looking for a wildcard // entry (i.e., change "/service/method" to "/service/"). - if (value == nullptr) { - char* path_str = grpc_slice_to_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = (size_t)(sep - path_str); - char* buf = (char*)gpr_malloc(len + 1); // trailing NUL - memcpy(buf, path_str, len); - buf[len] = '\0'; - grpc_slice wildcard_path = grpc_slice_from_copied_string(buf); - gpr_free(buf); - value = parsed_method_configs_table_->Get(wildcard_path); - grpc_slice_unref_internal(wildcard_path); - gpr_free(path_str); - if (value == nullptr) return nullptr; - } - return *value; + UniquePtr path_str(grpc_slice_to_c_string(path)); + char* sep = strrchr(path_str.get(), '/') + 1; + if (sep == nullptr) return nullptr; // Shouldn't ever happen. + *sep = '\0'; + grpc_slice wildcard_path = grpc_slice_from_static_string(path_str.get()); + it = parsed_method_configs_map_.find(wildcard_path); + if (it != parsed_method_configs_map_.end()) return it->second; + // Try default method config, if set. + return default_method_config_vector_; } size_t ServiceConfig::RegisterParser(std::unique_ptr parser) { diff --git a/src/core/ext/filters/client_channel/service_config.h b/src/core/ext/filters/client_channel/service_config.h index 6e9ead52af9..3bba4ec1010 100644 --- a/src/core/ext/filters/client_channel/service_config.h +++ b/src/core/ext/filters/client_channel/service_config.h @@ -19,6 +19,8 @@ #include +#include + #include #include @@ -27,7 +29,7 @@ #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/error.h" #include "src/core/lib/json/json.h" -#include "src/core/lib/slice/slice_hash_table.h" +#include "src/core/lib/slice/slice_internal.h" // The main purpose of the code here is to parse the service config in // JSON form, which will look like this: @@ -129,6 +131,7 @@ class ServiceConfig : public RefCounted { grpc_error** error); ServiceConfig(std::string json_string, Json json, grpc_error** error); + ~ServiceConfig(); const std::string& json_string() const { return json_string_; } @@ -143,7 +146,8 @@ class ServiceConfig : public RefCounted { /// Retrieves the vector of parsed configs for the method identified /// by \a path. The lifetime of the returned vector and contained objects /// is tied to the lifetime of the ServiceConfig object. - const ParsedConfigVector* GetMethodParsedConfigVector(const grpc_slice& path); + const ParsedConfigVector* GetMethodParsedConfigVector( + const grpc_slice& path) const; /// Globally register a service config parser. On successful registration, it /// returns the index at which the parser was registered. On failure, -1 is @@ -162,15 +166,11 @@ class ServiceConfig : public RefCounted { grpc_error* ParseGlobalParams(); grpc_error* ParsePerMethodParams(); - // Returns a path string for the JSON name object specified by \a json. - // Returns null on error, and stores error in \a error. - static UniquePtr ParseJsonMethodName(const Json& json, - grpc_error** error); + // Returns a path string for the JSON name object specified by json. + // Sets *error on error. + static std::string ParseJsonMethodName(const Json& json, grpc_error** error); - grpc_error* ParseJsonMethodConfigToServiceConfigVectorTable( - const Json& json, - InlinedVector::Entry, 10>* - entries); + grpc_error* ParseJsonMethodConfig(const Json& json); std::string json_string_; Json json_; @@ -180,8 +180,10 @@ class ServiceConfig : public RefCounted { // A map from the method name to the parsed config vector. Note that we are // using a raw pointer and not a unique pointer so that we can use the same // vector for multiple names. - RefCountedPtr> - parsed_method_configs_table_; + std::unordered_map + parsed_method_configs_map_; + // Default method config. + const ParsedConfigVector* default_method_config_vector_ = nullptr; // Storage for all the vectors that are being used in // parsed_method_configs_table_. InlinedVector, 32> diff --git a/src/core/ext/filters/client_channel/xds/xds_api.cc b/src/core/ext/filters/client_channel/xds/xds_api.cc index 76558647ee2..eca6f52a0df 100644 --- a/src/core/ext/filters/client_channel/xds/xds_api.cc +++ b/src/core/ext/filters/client_channel/xds/xds_api.cc @@ -1336,7 +1336,7 @@ grpc_error* LocalityParse( grpc_error* DropParseAndAppend( const envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload* drop_overload, - XdsApi::DropConfig* drop_config, bool* drop_all) { + XdsApi::DropConfig* drop_config) { // Get the category. upb_strview category = envoy_api_v2_ClusterLoadAssignment_Policy_DropOverload_category( @@ -1367,13 +1367,12 @@ grpc_error* DropParseAndAppend( } // Cap numerator to 1000000. numerator = GPR_MIN(numerator, 1000000); - if (numerator == 1000000) *drop_all = true; drop_config->AddCategory(std::string(category.data, category.size), numerator); return GRPC_ERROR_NONE; } -grpc_error* EdsResponsedParse( +grpc_error* EdsResponseParse( XdsClient* client, TraceFlag* tracer, const envoy_api_v2_DiscoveryResponse* response, const std::set& expected_eds_service_names, @@ -1423,6 +1422,14 @@ grpc_error* EdsResponsedParse( if (locality.lb_weight == 0) continue; eds_update.priority_list_update.Add(locality); } + for (uint32_t priority = 0; + priority < eds_update.priority_list_update.size(); ++priority) { + auto* locality_map = eds_update.priority_list_update.Find(priority); + if (locality_map == nullptr || locality_map->size() == 0) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "EDS update includes sparse priority list"); + } + } // Get the drop config. eds_update.drop_config = MakeRefCounted(); const envoy_api_v2_ClusterLoadAssignment_Policy* policy = @@ -1435,13 +1442,13 @@ grpc_error* EdsResponsedParse( policy, &drop_size); for (size_t j = 0; j < drop_size; ++j) { grpc_error* error = - DropParseAndAppend(drop_overload[j], eds_update.drop_config.get(), - &eds_update.drop_all); + DropParseAndAppend(drop_overload[j], eds_update.drop_config.get()); if (error != GRPC_ERROR_NONE) return error; } } // Validate the update content. - if (eds_update.priority_list_update.empty() && !eds_update.drop_all) { + if (eds_update.priority_list_update.empty() && + !eds_update.drop_config->drop_all()) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "EDS response doesn't contain any valid " "locality but doesn't require to drop all calls."); @@ -1497,9 +1504,9 @@ grpc_error* XdsApi::ParseAdsResponse( return CdsResponseParse(client_, tracer_, response, expected_cluster_names, cds_update_map, arena.ptr()); } else if (*type_url == kEdsTypeUrl) { - return EdsResponsedParse(client_, tracer_, response, - expected_eds_service_names, eds_update_map, - arena.ptr()); + return EdsResponseParse(client_, tracer_, response, + expected_eds_service_names, eds_update_map, + arena.ptr()); } else { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Unsupported ADS resource type."); diff --git a/src/core/ext/filters/client_channel/xds/xds_api.h b/src/core/ext/filters/client_channel/xds/xds_api.h index caa2c748a97..dc42681ecb4 100644 --- a/src/core/ext/filters/client_channel/xds/xds_api.h +++ b/src/core/ext/filters/client_channel/xds/xds_api.h @@ -25,12 +25,13 @@ #include +#include "absl/types/optional.h" + #include #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/xds/xds_bootstrap.h" #include "src/core/ext/filters/client_channel/xds/xds_client_stats.h" -#include "src/core/lib/gprpp/optional.h" namespace grpc_core { @@ -47,18 +48,35 @@ class XdsApi { std::string service; std::string method; std::string cluster_name; + + bool operator==(const RdsRoute& other) const { + return (service == other.service && + method == other.method && + cluster_name == other.cluster_name); + } }; struct RdsUpdate { std::vector routes; + + bool operator==(const RdsUpdate& other) const { + return routes == other.routes; + } }; + // TODO(roth): When we can use absl::variant<>, consider using that + // here, to enforce the fact that only one of the two fields can be set. struct LdsUpdate { // The name to use in the RDS request. std::string route_config_name; // The name to use in the CDS request. Present if the LDS response has it // inlined. - Optional rds_update; + absl::optional rds_update; + + bool operator==(const LdsUpdate& other) const { + return route_config_name == other.route_config_name && + rds_update == other.rds_update; + } }; using LdsUpdateMap = std::map; @@ -73,7 +91,7 @@ class XdsApi { // If not set, load reporting will be disabled. // If set to the empty string, will use the same server we obtained the CDS // data from. - Optional lrs_load_reporting_server_name; + absl::optional lrs_load_reporting_server_name; }; using CdsUpdateMap = std::map; @@ -157,6 +175,7 @@ class XdsApi { void AddCategory(std::string name, uint32_t parts_per_million) { drop_category_list_.emplace_back( DropCategory{std::move(name), parts_per_million}); + if (parts_per_million == 1000000) drop_all_ = true; } // The only method invoked from the data plane combiner. @@ -166,6 +185,8 @@ class XdsApi { return drop_category_list_; } + bool drop_all() const { return drop_all_; } + bool operator==(const DropConfig& other) const { return drop_category_list_ == other.drop_category_list_; } @@ -173,19 +194,19 @@ class XdsApi { private: DropCategoryList drop_category_list_; + bool drop_all_ = false; }; struct EdsUpdate { PriorityListUpdate priority_list_update; RefCountedPtr drop_config; - bool drop_all = false; }; using EdsUpdateMap = std::map; struct ClusterLoadReport { XdsClusterDropStats::DroppedRequestsMap dropped_requests; - std::map, XdsClusterLocalityStats::Snapshot, XdsLocalityName::Less> locality_stats; grpc_millis load_report_interval; diff --git a/src/core/ext/filters/client_channel/xds/xds_channel.cc b/src/core/ext/filters/client_channel/xds/xds_channel.cc index ffb92064f7c..1a3cf54cf0d 100644 --- a/src/core/ext/filters/client_channel/xds/xds_channel.cc +++ b/src/core/ext/filters/client_channel/xds/xds_channel.cc @@ -30,8 +30,12 @@ grpc_channel_args* ModifyXdsChannelArgs(grpc_channel_args* args) { grpc_channel* CreateXdsChannel(const XdsBootstrap& bootstrap, const grpc_channel_args& args, - grpc_error** /*error*/) { - if (!bootstrap.server().channel_creds.empty()) return nullptr; + grpc_error** error) { + if (!bootstrap.server().channel_creds.empty()) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "credential specified but gRPC not built with security"); + return nullptr; + } return grpc_insecure_channel_create(bootstrap.server().server_uri.c_str(), &args, nullptr); } diff --git a/src/core/ext/filters/client_channel/xds/xds_client.cc b/src/core/ext/filters/client_channel/xds/xds_client.cc index c9679da7b42..db5f33ecc7a 100644 --- a/src/core/ext/filters/client_channel/xds/xds_client.cc +++ b/src/core/ext/filters/client_channel/xds/xds_client.cc @@ -332,7 +332,6 @@ class XdsClient::ChannelState::LrsCallState void Orphan() override; void MaybeStartReportingLocked(); - bool ShouldSendLoadReports(const StringView& cluster_name) const; RetryableCall* parent() { return parent_.get(); } ChannelState* chand() const { return parent_->chand(); } @@ -735,7 +734,8 @@ XdsClient::ChannelState::AdsCallState::AdsCallState( grpc_op* op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; - op->flags = 0; + op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY | + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET; op->reserved = nullptr; op++; call_error = grpc_call_start_batch_and_execute(call_, ops, (size_t)(op - ops), @@ -746,6 +746,11 @@ XdsClient::ChannelState::AdsCallState::AdsCallState( grpc_schedule_on_exec_ctx); if (xds_client()->service_config_watcher_ != nullptr) { Subscribe(XdsApi::kLdsTypeUrl, xds_client()->server_name_); + if (xds_client()->lds_result_.has_value() && + !xds_client()->lds_result_->route_config_name.empty()) { + Subscribe(XdsApi::kRdsTypeUrl, + xds_client()->lds_result_->route_config_name); + } } for (const auto& p : xds_client()->cluster_map_) { Subscribe(XdsApi::kCdsTypeUrl, std::string(p.first)); @@ -831,11 +836,12 @@ void XdsClient::ChannelState::AdsCallState::SendMessageLocked( GRPC_ERROR_REF(state.error), !sent_initial_message_); state.subscribed_resources[xds_client()->server_name_]->Start(Ref()); } else if (type_url == XdsApi::kRdsTypeUrl) { - resource_names.insert(xds_client()->route_config_name_); + resource_names.insert(xds_client()->lds_result_->route_config_name); request_payload_slice = xds_client()->api_.CreateRdsRequest( - xds_client()->route_config_name_, state.version, state.nonce, - GRPC_ERROR_REF(state.error), !sent_initial_message_); - state.subscribed_resources[xds_client()->route_config_name_]->Start(Ref()); + xds_client()->lds_result_->route_config_name, state.version, + state.nonce, GRPC_ERROR_REF(state.error), !sent_initial_message_); + state.subscribed_resources[xds_client()->lds_result_->route_config_name] + ->Start(Ref()); } else if (type_url == XdsApi::kCdsTypeUrl) { resource_names = ClusterNamesForRequest(); request_payload_slice = xds_client()->api_.CreateCdsRequest( @@ -921,7 +927,10 @@ void XdsClient::ChannelState::AdsCallState::AcceptLdsUpdate( if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) { gpr_log(GPR_INFO, "[xds_client %p] LDS update received: route_config_name=%s", - xds_client(), lds_update->route_config_name.c_str()); + xds_client(), + (!lds_update->route_config_name.empty() + ? lds_update->route_config_name.c_str() + : "")); if (lds_update->rds_update.has_value()) { for (const auto& route : lds_update->rds_update.value().routes) { gpr_log(GPR_INFO, @@ -935,18 +944,28 @@ void XdsClient::ChannelState::AdsCallState::AcceptLdsUpdate( auto& lds_state = state_map_[XdsApi::kLdsTypeUrl]; auto& state = lds_state.subscribed_resources[xds_client()->server_name_]; if (state != nullptr) state->Finish(); - if (!xds_client()->route_config_name_.empty()) { + // Ignore identical update. + if (xds_client()->lds_result_ == lds_update) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) { + gpr_log(GPR_INFO, + "[xds_client %p] LDS update identical to current, ignoring.", + xds_client()); + } + return; + } + if (xds_client()->lds_result_.has_value() && + !xds_client()->lds_result_->route_config_name.empty()) { Unsubscribe( - XdsApi::kRdsTypeUrl, xds_client()->route_config_name_, + XdsApi::kRdsTypeUrl, xds_client()->lds_result_->route_config_name, /*delay_unsubscription=*/!lds_update->route_config_name.empty()); } - xds_client()->route_config_name_ = lds_update->route_config_name; - if (lds_update->rds_update.has_value()) { - // If the RouteConfiguration was found inlined in LDS response, notify the - // watcher immediately. + xds_client()->lds_result_ = std::move(lds_update); + if (xds_client()->lds_result_->rds_update.has_value()) { + // If the RouteConfiguration was found inlined in LDS response, notify + // the watcher immediately. RefCountedPtr service_config; grpc_error* error = xds_client()->CreateServiceConfig( - lds_update->rds_update.value(), &service_config); + xds_client()->lds_result_->rds_update.value(), &service_config); if (error == GRPC_ERROR_NONE) { xds_client()->service_config_watcher_->OnServiceConfigChanged( std::move(service_config)); @@ -955,7 +974,8 @@ void XdsClient::ChannelState::AdsCallState::AcceptLdsUpdate( } } else { // Send RDS request for dynamic resolution. - Subscribe(XdsApi::kRdsTypeUrl, xds_client()->route_config_name_); + Subscribe(XdsApi::kRdsTypeUrl, + xds_client()->lds_result_->route_config_name); } } @@ -972,12 +992,23 @@ void XdsClient::ChannelState::AdsCallState::AcceptRdsUpdate( } auto& rds_state = state_map_[XdsApi::kRdsTypeUrl]; auto& state = - rds_state.subscribed_resources[xds_client()->route_config_name_]; + rds_state + .subscribed_resources[xds_client()->lds_result_->route_config_name]; if (state != nullptr) state->Finish(); + // Ignore identical update. + if (xds_client()->rds_result_ == rds_update) { + if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) { + gpr_log(GPR_INFO, + "[xds_client %p] RDS update identical to current, ignoring.", + xds_client()); + } + return; + } + xds_client()->rds_result_ = std::move(rds_update); // Notify the watcher. RefCountedPtr service_config; - grpc_error* error = - xds_client()->CreateServiceConfig(rds_update.value(), &service_config); + grpc_error* error = xds_client()->CreateServiceConfig( + xds_client()->rds_result_.value(), &service_config); if (error == GRPC_ERROR_NONE) { xds_client()->service_config_watcher_->OnServiceConfigChanged( std::move(service_config)); @@ -1074,7 +1105,7 @@ void XdsClient::ChannelState::AdsCallState::AcceptEdsUpdate( " drop categories received (drop_all=%d)", xds_client(), eds_update.priority_list_update.size(), eds_update.drop_config->drop_category_list().size(), - eds_update.drop_all); + eds_update.drop_config->drop_all()); for (size_t priority = 0; priority < eds_update.priority_list_update.size(); ++priority) { const auto* locality_map_update = eds_update.priority_list_update.Find( @@ -1222,7 +1253,10 @@ void XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked( std::string type_url; // Note that ParseAdsResponse() also validates the response. grpc_error* parse_error = xds_client->api_.ParseAdsResponse( - response_slice, xds_client->server_name_, xds_client->route_config_name_, + response_slice, xds_client->server_name_, + (xds_client->lds_result_.has_value() + ? xds_client->lds_result_->route_config_name + : ""), ads_calld->ClusterNamesForRequest(), ads_calld->EdsServiceNamesForRequest(), &lds_update, &rds_update, &cds_update_map, &eds_update_map, &version, &nonce, &type_url); @@ -1416,7 +1450,7 @@ bool LoadReportCountersAreZero(const XdsApi::ClusterLoadReportMap& snapshot) { void XdsClient::ChannelState::LrsCallState::Reporter::SendReportLocked() { // Construct snapshot from all reported stats. XdsApi::ClusterLoadReportMap snapshot = - xds_client()->BuildLoadReportSnapshot(); + xds_client()->BuildLoadReportSnapshot(parent_->cluster_names_); // Skip client load report if the counters were all zero in the last // report and they are still zero in this one. const bool old_val = last_report_counters_were_zero_; @@ -1462,6 +1496,12 @@ void XdsClient::ChannelState::LrsCallState::Reporter::OnReportDoneLocked( Reporter* self = static_cast(arg); grpc_byte_buffer_destroy(self->parent_->send_message_payload_); self->parent_->send_message_payload_ = nullptr; + // If there are no more registered stats to report, cancel the call. + if (self->xds_client()->load_report_map_.empty()) { + self->parent_->chand()->StopLrsCall(); + self->Unref(DEBUG_LOCATION, "Reporter+report_done+no_more_reporters"); + return; + } if (error != GRPC_ERROR_NONE || !self->IsCurrentReporterOnCall()) { // If this reporter is no longer the current one on the call, the reason // might be that it was orphaned for a new one due to config update. @@ -1517,7 +1557,8 @@ XdsClient::ChannelState::LrsCallState::LrsCallState( grpc_op* op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; - op->flags = 0; + op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY | + GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET; op->reserved = nullptr; op++; // Op: send request message. @@ -1615,13 +1656,6 @@ void XdsClient::ChannelState::LrsCallState::MaybeStartReportingLocked() { Ref(DEBUG_LOCATION, "LRS+load_report+start"), load_reporting_interval_); } -bool XdsClient::ChannelState::LrsCallState::ShouldSendLoadReports( - const StringView& cluster_name) const { - // Only send load reports for the clusters that are asked for by the LRS - // server. - return cluster_names_.find(std::string(cluster_name)) != cluster_names_.end(); -} - void XdsClient::ChannelState::LrsCallState::OnInitialRequestSent( void* arg, grpc_error* error) { LrsCallState* lrs_calld = static_cast(arg); @@ -1968,19 +2002,14 @@ void XdsClient::RemoveClusterDropStats( LoadReportState& load_report_state = load_report_it->second; // TODO(roth): When we add support for direct federation, use the // server name specified in lrs_server. - // TODO(roth): In principle, we should try to send a final load report - // containing whatever final stats have been accumulated since the - // last load report. auto it = load_report_state.drop_stats.find(cluster_drop_stats); if (it != load_report_state.drop_stats.end()) { - load_report_state.drop_stats.erase(it); - if (load_report_state.drop_stats.empty() && - load_report_state.locality_stats.empty()) { - load_report_map_.erase(load_report_it); - if (chand_ != nullptr && load_report_map_.empty()) { - chand_->StopLrsCall(); - } + // Record final drop stats in deleted_drop_stats, which will be + // added to the next load report. + for (const auto& p : cluster_drop_stats->GetSnapshotAndReset()) { + load_report_state.deleted_drop_stats[p.first] += p.second; } + load_report_state.drop_stats.erase(it); } } @@ -2001,7 +2030,7 @@ RefCountedPtr XdsClient::AddClusterLocalityStats( Ref(DEBUG_LOCATION, "LocalityStats"), lrs_server, it->first.first /*cluster_name*/, it->first.second /*eds_service_name*/, locality); - it->second.locality_stats[std::move(locality)].insert( + it->second.locality_stats[std::move(locality)].locality_stats.insert( cluster_locality_stats.get()); chand_->MaybeStartLrsCall(); return cluster_locality_stats; @@ -2017,25 +2046,16 @@ void XdsClient::RemoveClusterLocalityStats( LoadReportState& load_report_state = load_report_it->second; // TODO(roth): When we add support for direct federation, use the // server name specified in lrs_server. - // TODO(roth): In principle, we should try to send a final load report - // containing whatever final stats have been accumulated since the - // last load report. auto locality_it = load_report_state.locality_stats.find(locality); if (locality_it == load_report_state.locality_stats.end()) return; - auto& locality_set = locality_it->second; + auto& locality_set = locality_it->second.locality_stats; auto it = locality_set.find(cluster_locality_stats); if (it != locality_set.end()) { + // Record final snapshot in deleted_locality_stats, which will be + // added to the next load report. + locality_it->second.deleted_locality_stats.emplace_back( + cluster_locality_stats->GetSnapshotAndReset()); locality_set.erase(it); - if (locality_set.empty()) { - load_report_state.locality_stats.erase(locality_it); - if (load_report_state.locality_stats.empty() && - load_report_state.drop_stats.empty()) { - load_report_map_.erase(load_report_it); - if (chand_ != nullptr && load_report_map_.empty()) { - chand_->StopLrsCall(); - } - } - } } } @@ -2088,32 +2108,70 @@ grpc_error* XdsClient::CreateServiceConfig( return error; } -XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshot() { +XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshot( + const std::set& clusters) { XdsApi::ClusterLoadReportMap snapshot_map; - for (auto& p : load_report_map_) { - const auto& cluster_key = p.first; // cluster and EDS service name - LoadReportState& load_report = p.second; - XdsApi::ClusterLoadReport& snapshot = snapshot_map[cluster_key]; + for (auto load_report_it = load_report_map_.begin(); + load_report_it != load_report_map_.end();) { + // Cluster key is cluster and EDS service name. + const auto& cluster_key = load_report_it->first; + LoadReportState& load_report = load_report_it->second; + // If the CDS response for a cluster indicates to use LRS but the + // LRS server does not say that it wants reports for this cluster, + // then we'll have stats objects here whose data we're not going to + // include in the load report. However, we still need to clear out + // the data from the stats objects, so that if the LRS server starts + // asking for the data in the future, we don't incorrectly include + // data from previous reporting intervals in that future report. + const bool record_stats = + clusters.find(cluster_key.first) != clusters.end(); + XdsApi::ClusterLoadReport snapshot; // Aggregate drop stats. + snapshot.dropped_requests = std::move(load_report.deleted_drop_stats); for (auto& drop_stats : load_report.drop_stats) { for (const auto& p : drop_stats->GetSnapshotAndReset()) { snapshot.dropped_requests[p.first] += p.second; } } // Aggregate locality stats. - for (auto& p : load_report.locality_stats) { - XdsLocalityName* locality_name = p.first.get(); - auto& locality_stats_set = p.second; + for (auto it = load_report.locality_stats.begin(); + it != load_report.locality_stats.end();) { + const RefCountedPtr& locality_name = it->first; + auto& locality_state = it->second; XdsClusterLocalityStats::Snapshot& locality_snapshot = snapshot.locality_stats[locality_name]; - for (auto& locality_stats : locality_stats_set) { + for (auto& locality_stats : locality_state.locality_stats) { locality_snapshot += locality_stats->GetSnapshotAndReset(); } + // Add final snapshots from recently deleted locality stats objects. + for (auto& deleted_locality_stats : + locality_state.deleted_locality_stats) { + locality_snapshot += deleted_locality_stats; + } + locality_state.deleted_locality_stats.clear(); + // If the only thing left in this entry was final snapshots from + // deleted locality stats objects, remove the entry. + if (locality_state.locality_stats.empty()) { + it = load_report.locality_stats.erase(it); + } else { + ++it; + } + } + if (record_stats) { + // Compute load report interval. + const grpc_millis now = ExecCtx::Get()->Now(); + snapshot.load_report_interval = now - load_report.last_report_time; + load_report.last_report_time = now; + // Record snapshot. + snapshot_map[cluster_key] = std::move(snapshot); + } + // If the only thing left in this entry was final snapshots from + // deleted stats objects, remove the entry. + if (load_report.locality_stats.empty() && load_report.drop_stats.empty()) { + load_report_it = load_report_map_.erase(load_report_it); + } else { + ++load_report_it; } - // Compute load report interval. - const grpc_millis now = ExecCtx::Get()->Now(); - snapshot.load_report_interval = now - load_report.last_report_time; - load_report.last_report_time = now; } return snapshot_map; } diff --git a/src/core/ext/filters/client_channel/xds/xds_client.h b/src/core/ext/filters/client_channel/xds/xds_client.h index 76a45c9b09f..e958d016bce 100644 --- a/src/core/ext/filters/client_channel/xds/xds_client.h +++ b/src/core/ext/filters/client_channel/xds/xds_client.h @@ -21,13 +21,14 @@ #include +#include "absl/types/optional.h" + #include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/xds/xds_api.h" #include "src/core/ext/filters/client_channel/xds/xds_bootstrap.h" #include "src/core/ext/filters/client_channel/xds/xds_client_stats.h" #include "src/core/lib/gprpp/map.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/gprpp/optional.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -208,8 +209,14 @@ class XdsClient : public InternallyRefCounted { }; struct LoadReportState { + struct LocalityState { + std::set locality_stats; + std::vector deleted_locality_stats; + }; + std::set drop_stats; - std::map, std::set, + XdsClusterDropStats::DroppedRequestsMap deleted_drop_stats; + std::map, LocalityState, XdsLocalityName::Less> locality_stats; grpc_millis last_report_time = ExecCtx::Get()->Now(); @@ -222,7 +229,8 @@ class XdsClient : public InternallyRefCounted { const XdsApi::RdsUpdate& rds_update, RefCountedPtr* service_config) const; - XdsApi::ClusterLoadReportMap BuildLoadReportSnapshot(); + XdsApi::ClusterLoadReportMap BuildLoadReportSnapshot( + const std::set& clusters); // Channel arg vtable functions. static void* ChannelArgCopy(void* p); @@ -246,7 +254,9 @@ class XdsClient : public InternallyRefCounted { // The channel for communicating with the xds server. OrphanablePtr chand_; - std::string route_config_name_; + absl::optional lds_result_; + absl::optional rds_result_; + // One entry for each watched CDS resource. std::map cluster_map_; // One entry for each watched EDS resource. diff --git a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h index 99e27719712..c411fb2b96b 100644 --- a/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +++ b/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h @@ -27,6 +27,19 @@ #include "src/core/lib/gprpp/ref_counted.h" #include "src/core/lib/security/security_connector/ssl_utils.h" +struct grpc_tls_error_details + : public grpc_core::RefCounted { + public: + grpc_tls_error_details() : error_details_("") {} + void set_error_details(const char* err_details) { + error_details_ = err_details; + } + const std::string& error_details() { return error_details_; } + + private: + std::string error_details_; +}; + /** TLS key materials config. **/ struct grpc_tls_key_materials_config : public grpc_core::RefCounted { @@ -93,8 +106,8 @@ struct grpc_tls_credential_reload_config gpr_log(GPR_ERROR, "schedule API is nullptr"); if (arg != nullptr) { arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL; - arg->error_details = - gpr_strdup("schedule API in credential reload config is nullptr"); + arg->error_details->set_error_details( + "schedule API in credential reload config is nullptr"); } return 1; } @@ -108,8 +121,8 @@ struct grpc_tls_credential_reload_config gpr_log(GPR_ERROR, "cancel API is nullptr."); if (arg != nullptr) { arg->status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL; - arg->error_details = - gpr_strdup("cancel API in credential reload config is nullptr"); + arg->error_details->set_error_details( + "cancel API in credential reload config is nullptr"); } return; } @@ -169,7 +182,7 @@ struct grpc_tls_server_authorization_check_config gpr_log(GPR_ERROR, "schedule API is nullptr"); if (arg != nullptr) { arg->status = GRPC_STATUS_NOT_FOUND; - arg->error_details = gpr_strdup( + arg->error_details->set_error_details( "schedule API in server authorization check config is nullptr"); } return 1; @@ -185,7 +198,7 @@ struct grpc_tls_server_authorization_check_config gpr_log(GPR_ERROR, "cancel API is nullptr."); if (arg != nullptr) { arg->status = GRPC_STATUS_NOT_FOUND; - arg->error_details = gpr_strdup( + arg->error_details->set_error_details( "schedule API in server authorization check config is nullptr"); } return; diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc index 47fdf3ff7fd..13180724cdc 100644 --- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -190,9 +190,10 @@ class grpc_ssl_channel_security_connector final grpc_auth_context* auth_context, grpc_closure* /*on_call_host_checked*/, grpc_error** error) override { - return grpc_ssl_check_call_host(host, target_name_.get(), - overridden_target_name_.get(), auth_context, - error); + return grpc_ssl_check_call_host( + host, target_name_.get(), + overridden_target_name_ != nullptr ? overridden_target_name_.get() : "", + auth_context, error); } void cancel_check_call_host(grpc_closure* /*on_call_host_checked*/, diff --git a/src/core/lib/security/security_connector/tls/tls_security_connector.cc b/src/core/lib/security/security_connector/tls/tls_security_connector.cc index f7b4df09881..ca361aa074f 100644 --- a/src/core/lib/security/security_connector/tls/tls_security_connector.cc +++ b/src/core/lib/security/security_connector/tls/tls_security_connector.cc @@ -88,6 +88,7 @@ grpc_status_code TlsFetchKeyMaterials( if (credential_reload_config != nullptr) { grpc_tls_credential_reload_arg* arg = new grpc_tls_credential_reload_arg(); arg->key_materials_config = key_materials_config.get(); + arg->error_details = new grpc_tls_error_details(); int result = credential_reload_config->Schedule(arg); if (result) { /** Credential reloading is performed async. This is not yet supported. @@ -105,13 +106,13 @@ grpc_status_code TlsFetchKeyMaterials( } else if (arg->status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL) { gpr_log(GPR_ERROR, "Credential reload failed with an error:"); if (arg->error_details != nullptr) { - gpr_log(GPR_ERROR, "%s", arg->error_details); + gpr_log(GPR_ERROR, "%s", arg->error_details->error_details().c_str()); } reload_status = is_key_materials_empty ? GRPC_STATUS_INTERNAL : GRPC_STATUS_OK; } } - gpr_free((void*)arg->error_details); + delete arg->error_details; /** If the credential reload config was constructed via a wrapped language, * then |arg->context| and |arg->destroy_context| will not be nullptr. In * this case, we must destroy |arg->context|, which stores the wrapped @@ -406,14 +407,14 @@ grpc_error* TlsChannelSecurityConnector::ProcessServerAuthorizationCheckResult( gpr_asprintf(&msg, "Server authorization check is cancelled by the caller with " "error: %s", - arg->error_details); + arg->error_details->error_details().c_str()); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); } else if (arg->status == GRPC_STATUS_OK) { /* Server authorization check completed successfully but returned check * failure. */ if (!arg->success) { gpr_asprintf(&msg, "Server authorization check failed with error: %s", - arg->error_details); + arg->error_details->error_details().c_str()); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); } /* Server authorization check did not complete correctly. */ @@ -421,7 +422,7 @@ grpc_error* TlsChannelSecurityConnector::ProcessServerAuthorizationCheckResult( gpr_asprintf( &msg, "Server authorization check did not finish correctly with error: %s", - arg->error_details); + arg->error_details->error_details().c_str()); error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); } gpr_free(msg); @@ -433,6 +434,7 @@ TlsChannelSecurityConnector::ServerAuthorizationCheckArgCreate( void* user_data) { grpc_tls_server_authorization_check_arg* arg = new grpc_tls_server_authorization_check_arg(); + arg->error_details = new grpc_tls_error_details(); arg->cb = ServerAuthorizationCheckDone; arg->cb_user_data = user_data; arg->status = GRPC_STATUS_OK; @@ -447,7 +449,7 @@ void TlsChannelSecurityConnector::ServerAuthorizationCheckArgDestroy( gpr_free((void*)arg->target_name); gpr_free((void*)arg->peer_cert); if (arg->peer_cert_full_chain) gpr_free((void*)arg->peer_cert_full_chain); - gpr_free((void*)arg->error_details); + delete arg->error_details; if (arg->destroy_context != nullptr) { arg->destroy_context(arg->context); } diff --git a/src/core/lib/slice/slice_internal.h b/src/core/lib/slice/slice_internal.h index e74aba94145..5148aad5055 100644 --- a/src/core/lib/slice/slice_internal.h +++ b/src/core/lib/slice/slice_internal.h @@ -347,4 +347,18 @@ size_t grpc_slice_memory_usage(grpc_slice s); grpc_core::UnmanagedMemorySlice grpc_slice_sub_no_ref( const grpc_core::UnmanagedMemorySlice& source, size_t begin, size_t end); +namespace grpc_core { + +struct SliceHash { + std::size_t operator()(const grpc_slice& slice) const { + return grpc_slice_hash_internal(slice); + } +}; + +} // namespace grpc_core + +inline bool operator==(const grpc_slice& s1, const grpc_slice& s2) { + return grpc_slice_eq(s1, s2); +} + #endif /* GRPC_CORE_LIB_SLICE_SLICE_INTERNAL_H */ diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc index 02c278dad65..cb74590db3d 100644 --- a/src/core/tsi/ssl_transport_security.cc +++ b/src/core/tsi/ssl_transport_security.cc @@ -35,6 +35,8 @@ #include #endif +#include "absl/strings/match.h" + #include #include #include @@ -1658,7 +1660,7 @@ static int does_entry_match_name(grpc_core::StringView entry, if (entry.empty()) return 0; } - if (name == entry) { + if (absl::EqualsIgnoreCase(name, entry)) { return 1; /* Perfect match. */ } if (entry.front() != '*') return 0; @@ -1685,7 +1687,7 @@ static int does_entry_match_name(grpc_core::StringView entry, if (name_subdomain.back() == '.') { name_subdomain.remove_suffix(1); } - return !entry.empty() && name_subdomain == entry; + return !entry.empty() && absl::EqualsIgnoreCase(name_subdomain, entry); } static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, @@ -1707,7 +1709,7 @@ static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, } } gpr_log(GPR_ERROR, "No match found for server name: %s.", servername); - return SSL_TLSEXT_ERR_ALERT_WARNING; + return SSL_TLSEXT_ERR_NOACK; } #if TSI_OPENSSL_ALPN_SUPPORT diff --git a/src/core/tsi/test_creds/README b/src/core/tsi/test_creds/README index eb8482d648f..645fe9fe502 100644 --- a/src/core/tsi/test_creds/README +++ b/src/core/tsi/test_creds/README @@ -6,7 +6,7 @@ Bad credentials (badclient.* / badserver.*): These are self-signed certificates: -$ openssl req -x509 -newkey rsa:1024 -keyout badserver.key -out badserver.pem \ +$ openssl req -x509 -newkey rsa:2048 -keyout badserver.key -out badserver.pem \ -days 3650 -nodes When prompted for certificate information, everything is default except the @@ -19,44 +19,71 @@ Valid test credentials: The ca is self-signed: ---------------------- -$ openssl req -x509 -new -newkey rsa:1024 -nodes -out ca.pem -config ca-openssl.cnf -days 3650 -extensions v3_req +$ openssl req -x509 -new -newkey rsa:2048 -nodes -keyout ca.key -out ca.pem \ + -config ca-openssl.cnf -days 3650 -extensions v3_req When prompted for certificate information, everything is default. client is issued by CA: ----------------------- -$ openssl genrsa -out client.key.rsa 1024 +$ openssl genrsa -out client.key.rsa 2048 $ openssl pkcs8 -topk8 -in client.key.rsa -out client.key -nocrypt -$ rm client.key.rsa $ openssl req -new -key client.key -out client.csr When prompted for certificate information, everything is default except the common name which is set to testclient. -$ openssl ca -in client.csr -out client.pem +$ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in client.csr \ + -out client.pem -days 3650 server0 is issued by CA: ------------------------ -$ openssl genrsa -out server0.key.rsa 1024 +$ openssl genrsa -out server0.key.rsa 2048 $ openssl pkcs8 -topk8 -in server0.key.rsa -out server0.key -nocrypt -$ rm server0.key.rsa $ openssl req -new -key server0.key -out server0.csr When prompted for certificate information, everything is default except the common name which is set to *.test.google.com.au. -$ openssl ca -in server0.csr -out server0.pem +$ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in server0.csr \ + -out server0.pem -days 3650 server1 is issued by CA with a special config for subject alternative names: ---------------------------------------------------------------------------- -$ openssl genrsa -out server1.key.rsa 1024 +$ openssl genrsa -out server1.key.rsa 2048 $ openssl pkcs8 -topk8 -in server1.key.rsa -out server1.key -nocrypt -$ rm server1.key.rsa $ openssl req -new -key server1.key -out server1.csr -config server1-openssl.cnf When prompted for certificate information, everything is default except the common name which is set to *.test.google.com. -$ openssl ca -in server1.csr -out server1.pem +$ openssl x509 -req -CA ca.pem -CAkey ca.key -CAcreateserial -in server1.csr \ + -out server1.pem -extensions req_ext -extfile server1-openssl.cnf -days 3650 + +Clean up: +--------- +$ rm *.rsa +$ rm *.csr +$ rm ca.srl + +Sync up with other repositories +=============================== + +Copies of these keys exist in multiple locations across all the grpc repos +(e.g., see the following partial list). You need to be careful when updating +the keys. + +grpc-dart/interop/ +grpc-dotnet/testassets/Certs/InteropTests/ +grpc-go/testdata/ +grpc-java/testing/src/main/resources/certs/ +grpc-node/test/data/ +src/csharp/Grpc.IntegrationTesting/data/ +src/objective-c/tests/TestCertificates.bundle/ +src/php/tests/data/ +src/python/grpcio_tests/tests/interop/credentials/ +src/python/grpcio_tests/tests/unit/credentials/ +src/ruby/spec/testdata/ +test/core/end2end/data/ diff --git a/src/core/tsi/test_creds/badclient.key b/src/core/tsi/test_creds/badclient.key index 5832685122a..6cd102b8308 100644 --- a/src/core/tsi/test_creds/badclient.key +++ b/src/core/tsi/test_creds/badclient.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALJfYnFn4nkj52WF -E5W2qUxCfjsEFyuXYYKS/07UPWsv3gpZhtjXgdeGL+dpwEBC0IRDBfGnkMp6YY5S -O7rnEz0X3r/fvgYy+dEl2jnaA6zgc7RzMGl9U11d56gP9FiDC2190mvP/hpq2xLZ -CTbIximpmaoQyxuuH1bbYunesIG/AgMBAAECgYAdqJCEzMIyZE7oaW0tOpcB0BiP -FYoIvH4BKRH8eHvR476mt+YdDhBP1scGUmYeCT4Ej+RgHv2LPTgVYwT9eciP2+E/ -CBCNRel0Sw9JepwW0r+jWJtDY1pp6YXAgNRGX2UflvUsT+o9lZvagf9moLTMyGvU -uLFnsyfLim1B4vXvWQJBANouZllXGZoSrZLtR3VgV4tzRQvJxu84kLeIk64Ov47X -pHVBMTRBfzPEhbBodjr1m5OLaVLqkFcXftzRCrbWoKsCQQDRSoLLXOiLrtJ3DLJC -rX7Y8wrHZrqk5bMdZLGa/UX8RanhVw3+Xp+urd1711umeNJfzu/MCk4a1KkG/CU0 -rqs9AkA4cSx1DD1JSG+yxMNpsAS1xJomFIrsM9vsPt7FdndDwrF+y+CovhDkGYDk -RAHh+svGfZg/pQK2JRPimAmHhzqFAkEAu6Ya70s2FUeB3Mu9aJs2CD6hg3dQEVkB -53DI7TX48d9kGW58VX1xnqS02LyWqAPcW5qm1kLHFLdndaPNmBaj4QJBAJugl367 -9d9t/QLTSuULLaoYv2vJT3s1y9HN89EoaDDEkPVfQu6GVEXgIBtim1sI/VPSzI8H -aXvaTUwblFWSM70= +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvdzKDTYvRgjBO +UOrzDwkAZGwNFHHlMYyMGI5tItj3tCzXkbpM0uz3ZjHVahu+eYc+KvYApM64F2dB +b16hs713FCk8mihYABjnSndrQsl/U2v8YFT7DipfLReqqaOGu2o9HdvWfiUlaiC/ +UGGfR+YblpK7CG+7/hvTXtUsMw+OppoeH9z87rhOJMxtiC7XwU5rhEmab/1f1XM/ +nLoZrfDAcTbDywoeu826SJ3mifajq7oK3LDdNLjWZwfEsCO1qp2C4gLvBlOOKsWO +LNby6ByxCOPlCTa0UCaVuoNclYol71jyi17KW+Nk0nNe9yaVcyr6H0z3bImfJhbS +u4rzI93nAgMBAAECggEBAOIPOJRTpGaH7GpCYUpLK0g/hPFkF5EyEWg/1lSYzRIp ++RsX6zOS+zkiNHEv1jkeKNo7XDiHXM7U6RkQtdkZAQdk9PjM3sEUdm4CEnIjfmzA +p/R8TD0kxkNLIkhuFH2gd05y3ZHDS/XiFkAE9eOT0FrC7om6ESD7ZfFIWR18pncW +ZGq7tFAZZRmpkum2D+MJy1gWxIXBxt5madTEpRxQd56toEnfx372F0y4zkcX3pnE +4H6FaJUBjdvKl2QzF5c0jBqgxMRvWP5YfNu8+dmaQORPkpzSptOPmZM9VKV+tJVS +1xnOI6DtrnNZRojegR/E6KhNyiPTYy97UgYzdKS+SSECgYEA+wgSIqrfkeqqotJx +cGxF4x9v/ldKr5hlhJNoKXLkepkcrvhhxfHKgjWz1nZY/+Rpg42GFMvxWRrGTMIJ +ddiOr24p0HCkusWRMKQL7XxvuHDq0ro8SGqXzqWGuH31R+YNP8dy2pqd3OlwzTgg +8v0wwzx8AuyP5Ys4M20Ewv7Xuy0CgYEA9DSGMU8jmjxJ/uPDCXWOEAqtE78wTtIw +uMBv+ge0inc37xf+fN6D/ziTrJvgw/XyT15pmQdOlXx3Sg1h9XBZeIlaeCdFWrFB +oYrVsiuoXRswfkFwA0yOkCsHyGiI4TE0W1rGbqP158IjwXPczBswWI7i/D6LpINL +BD7YYpfHmeMCgYB08AiKr7Cf54H/gSqo5TcVGzLvdzhqXgKEZKp0DHpUhfivpTLe +o8jjKSMSN2U0JvHj/0xDadGO4YMYhJcll3C4VggSejaybpA46WJJCdt9PtSUv36P +eWAoOkFstfhJuufXGxDstnPtUa1jW881gi5x9D4MmqhZlKXkhtdeApr6LQKBgQDd +ItsJt9JTjpirGfC5lhwI5sIICa9jEO9RveEoluWkJYUfG6k1xgHdkYwYWCdXDFZa +DPKuwnEk6MrU4f181joO7sJf35/sGmuGL0SHzQTvGvn0uqkGM8M9RdoMXqzkzzvM +Jg1ej1bUgXcDbTnaEhzbdLiTFsg5NzMtKwOjdDIpZQKBgEIHeJIqiGjYgf7mUlX2 +vNWgFNlzApkFSCQ8TkzkDOjtCdSHfdRDJ6+q8cS2TSQ7QPoAlI1woS0G48TNbVSo +wD0jNVRTdpA6R5FPsg09ohB/caSn0zlGVha2GS08ceYrn7nn4PSZ/UIYTm3pjUlV +H5tvHv0gG2C5vy3tIYQtSQCk -----END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/badclient.pem b/src/core/tsi/test_creds/badclient.pem index 1785970221f..345da3932d9 100644 --- a/src/core/tsi/test_creds/badclient.pem +++ b/src/core/tsi/test_creds/badclient.pem @@ -1,17 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICoDCCAgmgAwIBAgIJANIz2/zoRiapMA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZGNsaWVudC50ZXN0Lmdvb2dsZS5j -b20wHhcNMTQwNzI4MjAwODI1WhcNMjQwNzI1MjAwODI1WjBpMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRjbGllbnQudGVzdC5nb29nbGUuY29tMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyX2JxZ+J5I+dlhROVtqlMQn47BBcr -l2GCkv9O1D1rL94KWYbY14HXhi/nacBAQtCEQwXxp5DKemGOUju65xM9F96/374G -MvnRJdo52gOs4HO0czBpfVNdXeeoD/RYgwttfdJrz/4aatsS2Qk2yMYpqZmqEMsb -rh9W22Lp3rCBvwIDAQABo1AwTjAdBgNVHQ4EFgQU523AJMR8Ds9V8fhf7gu1i0MM -UqAwHwYDVR0jBBgwFoAU523AJMR8Ds9V8fhf7gu1i0MMUqAwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQUFAAOBgQCI/tvSBYH1iyfLaCTBKwpdj36+MkR9EeJJmImx -X+bjhKWXwsBX4PDMWvdusr++QGUYtyoya+hfYMXRhXua39mD54xgloQNuu9REDwX -Ffto+aOw3BcYducz6ofxicFK/Y2VeXDurSMpRv5TfGf2Qr6eOOdaRhj6ed7BibHk -X1VGZA== +MIIDszCCApugAwIBAgIUONWbkUn1obHCw9L7lMNEE5REvb8wDQYJKoZIhvcNAQEL +BQAwaTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEiMCAGA1UEAwwZYmFkY2xpZW50LnRl +c3QuZ29vZ2xlLmNvbTAeFw0yMDAzMTcxNzQzMjNaFw0zMDAzMTUxNzQzMjNaMGkx +CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZGNsaWVudC50ZXN0Lmdv +b2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvdzKDTYvR +gjBOUOrzDwkAZGwNFHHlMYyMGI5tItj3tCzXkbpM0uz3ZjHVahu+eYc+KvYApM64 +F2dBb16hs713FCk8mihYABjnSndrQsl/U2v8YFT7DipfLReqqaOGu2o9HdvWfiUl +aiC/UGGfR+YblpK7CG+7/hvTXtUsMw+OppoeH9z87rhOJMxtiC7XwU5rhEmab/1f +1XM/nLoZrfDAcTbDywoeu826SJ3mifajq7oK3LDdNLjWZwfEsCO1qp2C4gLvBlOO +KsWOLNby6ByxCOPlCTa0UCaVuoNclYol71jyi17KW+Nk0nNe9yaVcyr6H0z3bImf +JhbSu4rzI93nAgMBAAGjUzBRMB0GA1UdDgQWBBTKJskEYd2ndrwihPTg2PzYF/kP +gzAfBgNVHSMEGDAWgBTKJskEYd2ndrwihPTg2PzYF/kPgzAPBgNVHRMBAf8EBTAD +AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBoGwWR0pLM1icX4bIJ6yduFU/A4jSiqET6 +gvJhwgErilqTKfH6Y89rqtzW8k4UurAOCsE4FA6wbkHWwrUMnClY4lkHJh+MuNaJ +nCGrK8wRKGb/mqW9d5pP72Et1Q6OW6DAKqGfjDWh2MzSPHBxcCLeyigO1wqd4W1T +nvvql6l4L+B5IT/c+/EHO3PwbI9v6MGTtLjsZgkRKItaPh+YeJdmBYhRD1BvWb6s +VwEb7aQ1oSF+esUvMmjGVuHXuQvWJahnjYdYT2DikyqR+AwaKzre4GJMHsX3/Cf8 +qdxyI+B1jUwNr7sLA2EYDjnUR0jEHcrOBSpIQyRMGWduj0P16yb9 -----END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/badserver.key b/src/core/tsi/test_creds/badserver.key index abfbde10ff6..1f5a31666cb 100644 --- a/src/core/tsi/test_creds/badserver.key +++ b/src/core/tsi/test_creds/badserver.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKeZ1e1y29cmBKaW -oIUwJ5neOJUjx+eD/3nRPe+dvLXEd9+db0fG5RYRR0S3mF1Ywuj4PIxlTW2YprUS -oGSw+tcqWNIzxv94HjwYFkkvER3AblXcDBh0P2zAkzg+nf9AcAsMh0QpDTyrXtMl -gqryjq1/vkhFofKMMbY+aXJdG6OBAgMBAAECgYAAgaB51S0A22aMMkxN2rVj6530 -JWWHN4jgD1fGj41wZyWNkWYyq1Ep3ed/N6bIMWp1VbqpGe0/9YQba/D8HOTFHGRt -72YXnP1e/ds8cxU4x4j1vvqSPtXpMmkiXfXijOvCl9mrMH2xjghFAt6/1Nb9xo1m -VdcOB8OdSuOIw6CI+QJBAN5FZUbS+bRXDWII/FaAih1DBpwCxhYEN+TXPJBxSen6 -kOzGt5g+mB6YqRMZ/qshshwPq7bsgFGfJ2lIdS2t3GsCQQDBCKifV5AAkOdOUrkK -HvoX3qnVmyIA8CyvWLcIWpfZ76QAYh0q0StedKdOMXaB1jTeSJ2KU1nlss7UD1Yw -VbrDAkAwjMHpbW3jiVw//Kx5jIwehiRscWKpLnSzBJyTBFvbwsJjJai2lX2OuVO8 -+2GYKb0Iyhd81j3VFkl6grwtpRtPAkB7+n+yt555fpfRKjhGU9b09cHGu7h/OcK5 -bBVCfE0DYHLI/DsXgPiF1g6Onh4rDdUu3xyv9xDKAqnscV099hHZAkEAvcFBfXZs -tk18N+bUcvXTdZjzZbfLCHlJmwPIspZ8G/6Pn63deg4GVYoCvTwGruah+8y734Ph -7PskfPgUQlB7Ag== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRY2Z886nT6KF4 +tjgJTX0l1M4j8bQp+jKfXz+hwUZbn/PnCXJlu/5denpyu4XrLxr6Ix4Il97SrKfQ +iGaSZQ8hcq6WQdEDfuo/U7R/dk6lYG7q+yg7+xHm02DzVdPLp09kLhU+fWH3Wek0 +9GCk9iC1/sVTIomBYpar61Ris04iA1QveR+LZKNkQ8rL2i191Djs8cdrn9yhWdfJ +Ai89lLl6S6d8cXru1LwtEe0ejctnKf6ANqMnmyWTbHV8h0Cc3fbAnx92HsWDMJKe +8mI0CClauxrlagMHyw10NuFb9/MBEkFPJfxcUyW6F45LmqGHVfcxx6/BU7XRbWx8 +aQM/pt2LAgMBAAECggEBAKWpei3D7op9FDvYF0+s4iXrT0j682r+y8xx5HtK2iql +y6fwPnUlHqPAwl5B5TtkonhjDmEIH0AZYBBJyrVqhWUWQfEZk4+rexOtWzI5XRHU +0QzSt0t1Yf15IcyEDDSlY9fD6gTt2HOFzE+cRVZecRTsxBv5SEd4w/KzFqmcaWXY +Q7mLvCs6eQ55LBQ6EMweZ3XE57qPf71oV8Ckxv/jstLlkE+3JICgEAaiOEzi7oCm +hYbkoU2VNewx5EA5ka52DQzbVYYYuDbjqtVPXCmlVdejBBmUCAlhdjAIDBYq/RMf +sVMagAo19Wt5lYuNGD9qzMUmzZPaVmkg4yUmU8EYFVkCgYEA8Tyup/0yx+/tp8KQ +cLyGc4RDUTfabL8mlvxcbEge9fQ12aHE3cA/hkHCI7AZxwrHYwb1hxzLaOmKYfFC +oLxfzx81p5BO0lQWcKiFZ6ISiku4TPdmBaauKKxd62kFUPO4Q6Zk1MFHMXrvZUxZ +BsK058HZ5JALDdQ5wBfJE5P58rcCgYEA3jPDMiXsH1s5gM/bh0s+cC1AFSst6YM3 +rRPmHrqJJhKgU6gSB0d0LCUdj4/NkQT/Bw8DrfxLIqytsfRLKCx85K6lk8GfCk6T +1OhPKRp8bgg6WDQiJfJMokJN5zrnC02ns1cVdQSPY8bFxB++tv3du6DKLYx0e46D +Q9ojYqWHh80CgYEA0Shh7nkTrFKUZZ3GClkK4eFNVH/uu9bIKKTJpYCqh2mjvvwJ +apKjAU7GepbW4sKvuWZxPyJyIpZKSz0ZHa/2CejvZkcycB5EDo2ujPnyxUF9nA3s +wP2RhuZb0B4QY+3MV6tPRUAG8Bm8ssGNdtUecMqclxVk4Cqfn7N/vZ/RWOUCgYAL +i2rv1xKOioHRVHtWay1iTKeQsf6frEafQnJpVE294afc0NWm9SpvBLqlc9Y9W6IY +bspFJt+MfKZFoaip/K28f+pwY9XshiqeHDfIreybFuhZHtRLXmxm3cUIZ4ILj0xQ +QA0IWGVOzMwHpZKWFViI4BDBDxQaO0xMoS/Hd0w0XQKBgF5uZXXrNLmCeU6oco1R +gjGJE4gRwaSVcVJbs/VLbBmHT1VhBGsiluBuTpbmzDfyHWHJprnthlSTgqHXSax1 +6GvHZ2NHBqmD2uxEGuwBffzhwWVxHpgSrRgvnnaeIph2Iv92/ATN5LCc5vF+SNGx +2kKWYTDSRu9q1xHpXcax+nmJ -----END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/badserver.pem b/src/core/tsi/test_creds/badserver.pem index 983c979f312..217dd640eba 100644 --- a/src/core/tsi/test_creds/badserver.pem +++ b/src/core/tsi/test_creds/badserver.pem @@ -1,17 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICoDCCAgmgAwIBAgIJAPdqwqsKNy81MA0GCSqGSIb3DQEBBQUAMGkxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZHNlcnZlci50ZXN0Lmdvb2dsZS5j -b20wHhcNMTQwNzI4MjAwODU0WhcNMjQwNzI1MjAwODU0WjBpMQswCQYDVQQGEwJB -VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 -cyBQdHkgTHRkMSIwIAYDVQQDDBliYWRzZXJ2ZXIudGVzdC5nb29nbGUuY29tMIGf -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnmdXtctvXJgSmlqCFMCeZ3jiVI8fn -g/950T3vnby1xHffnW9HxuUWEUdEt5hdWMLo+DyMZU1tmKa1EqBksPrXKljSM8b/ -eB48GBZJLxEdwG5V3AwYdD9swJM4Pp3/QHALDIdEKQ08q17TJYKq8o6tf75IRaHy -jDG2PmlyXRujgQIDAQABo1AwTjAdBgNVHQ4EFgQU3u/qvHr9knMBeZyAD7mAA/ec -8cUwHwYDVR0jBBgwFoAU3u/qvHr9knMBeZyAD7mAA/ec8cUwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQUFAAOBgQA/FmR1SGLguxCCfhp4CYCbrAePSyPWDi48gTwj -vVZf/OMxdVu/H8sBYFf27BjbrEugAw16DElFtgTZ83pLb2BvkUgb6vBUK5sEkgmh -z88zBsgDp8aCf4STDOLFZMBh/E9ZKkm1zogbEmlTjFp/ceSpa2gNv7OuN4WiorOh -Wvw40g== +MIIDszCCApugAwIBAgIULEum14ranwlUZjuZchSWaHtj8Z4wDQYJKoZIhvcNAQEL +BQAwaTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEiMCAGA1UEAwwZYmFkc2VydmVyLnRl +c3QuZ29vZ2xlLmNvbTAeFw0yMDAzMTcxNzE5NTRaFw0zMDAzMTUxNzE5NTRaMGkx +CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQxIjAgBgNVBAMMGWJhZHNlcnZlci50ZXN0Lmdv +b2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRY2Z886nT +6KF4tjgJTX0l1M4j8bQp+jKfXz+hwUZbn/PnCXJlu/5denpyu4XrLxr6Ix4Il97S +rKfQiGaSZQ8hcq6WQdEDfuo/U7R/dk6lYG7q+yg7+xHm02DzVdPLp09kLhU+fWH3 +Wek09GCk9iC1/sVTIomBYpar61Ris04iA1QveR+LZKNkQ8rL2i191Djs8cdrn9yh +WdfJAi89lLl6S6d8cXru1LwtEe0ejctnKf6ANqMnmyWTbHV8h0Cc3fbAnx92HsWD +MJKe8mI0CClauxrlagMHyw10NuFb9/MBEkFPJfxcUyW6F45LmqGHVfcxx6/BU7XR +bWx8aQM/pt2LAgMBAAGjUzBRMB0GA1UdDgQWBBTYP9Av5QoPxsDRE33wQedENOke +wDAfBgNVHSMEGDAWgBTYP9Av5QoPxsDRE33wQedENOkewDAPBgNVHRMBAf8EBTAD +AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCXA/Ewb5laDDxJi4YJxnmqQsb4WSsm65Hj +MX21Ii2vzf4XZ+i8c9xBezCae85Bkhtb/oMC/V15DshjVkkJNmdQfAlYD1NASSrN +hTaiQ4AfXWjO7H8o2B/rneZtA21NDCwvFxTXeJzAVnBkpIePR//KmuHjtCMjsrtP +ovckcTRGmhWJJ9sRx4HCsJXygBvnCIIIYC585aU4+nE53UDNT2T+Bd4b1vPmwf9R +9XgbyN6AhQ+0F11zlnftwsJ23nbnXqX/fpG/YZuhnPwaUILRodc6HZQtf/8xpRcA +0dKMdnL2YtBjuL5QFJMLT0mdsmnXj3h/oK8894nYBZYSmlb3bzZK -----END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/ca.key b/src/core/tsi/test_creds/ca.key index 03c4f950e38..03be0bfa6ee 100644 --- a/src/core/tsi/test_creds/ca.key +++ b/src/core/tsi/test_creds/ca.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMBA3wVeTGHZR1Ry -e/i+J8a2cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBl -LoNY0lSvxDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JA -HUGodjx+QAi6yCAurUZGvYXGgZSBAgMBAAECgYAxRi8i9BlFlufGSBVoGmydbJOm -bwLKl9dP3o33ODSP9hok5y6A0w5plWk3AJSF1hPLleK9VcSKYGYnt0clmPVHF35g -bx2rVK8dOT0mn7rz9Zr70jcSz1ETA2QonHZ+Y+niLmcic9At6hRtWiewblUmyFQm -GwggIzi7LOyEUHrEcQJBAOXxyQvnLvtKzXiqcsW/K6rExqVJVk+KF0fzzVyMzTJx -HRBxUVgvGdEJT7j+7P2kcTyafve0BBzDSPIaDyiJ+Y0CQQDWCb7jASFSbu5M3Zcd -Gkr4ZKN1XO3VLQX10b22bQYdF45hrTN2tnzRvVUR4q86VVnXmiGiTqmLkXcA2WWf -pHfFAkAhv9olUBo6MeF0i3frBEMRfm41hk0PwZHnMqZ6pgPcGnQMnMU2rzsXzkkQ -OwJnvAIOxhJKovZTjmofdqmw5odlAkBYVUdRWjsNUTjJwj3GRf6gyq/nFMYWz3EB -RWFdM1ttkDYzu45ctO2IhfHg4sPceDMO1s6AtKQmNI9/azkUjITdAkApNa9yFRzc -TBaDNPd5KVd58LVIzoPQ6i7uMHteLXJUWqSroji6S3s4gKMFJ/dO+ZXIlgQgfJJJ -ZDL4cdrdkeoM +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwYvShd+UXQvOg +z4GH6pRT3KGrPDbDw45fma7+I0LJQ4GupoeLuYYfHvcYPTV2I3MLO+VxCp00gfo1 +BIvsNOkGNxrrqNhP27ve9l7YwOuvWdVu4u9+73znRx3GJQ4ie/nF/z6xMcbQL5r5 +UC8yGwuJGOyr6VcpEnKTnORtuwRPJuqnGgn4rsKhLLfJz+RAhjdOKnAS3CQo/iHP +KjoqIZ38M97GJ7icFQic3dtLUFR41nnN5ogLZ6DduR55btypPnlv5h6foLFjRMST +MEroAq39ZSJqUoyBPTBtPFFk7uRQIfdKrp7/Bd4V0n4e91Us+UCDlOcxo2lF1CKH +/ydEWmx3AgMBAAECggEAKrDosKQKKKUlvkg6+6CFIf8GiiFax+ru7KiPuCbkpT3X +h2P67pCKq8Gc4Jr/84YE9DUdBU0iW3ESE/7ztsnflIeF1n/ZSwrN39sVfbTD1n8R +r3LxsHFac8e8pxaU4zfKbmemztBTZFQBWFJV+fSdyCLmNX2WgPRcEuooR366PkWv +xZLAxeDGqpnsa62o1GdGmalxx8aljLN/QcbQi73mR9Osim1OtSd1cyDlZ/8x6OoV +Ae5GDN3Bj0hO9ZKzNWTbQpRw9SHKU6sWXtHlcDx4xi5kN/n9aptn7kixbY9y8uOM +5zjErVGWvxdP94IvlSkrkenwnIjlHBtdlAjVuCFioQKBgQDoJLyfHNWPBnjPGVnK +xcbIIwmf4C9UnZBbHRD3YxU/GBpsPgPh9EwhQTAXlGQGHeuslxCIh4cEfbOIrJ9b +/s3OqeL9CSUaz/N+1av1ZuwOI9CEvNPi51IK+rXNRmVJG8pG6RaKNx57pXaFtmqq +FUtC7twbPECvjspapn61nZYSiQKBgQDCg1tpGwZJJOCIkhYH4wFc4j4p0LxIcBJ2 +E3L9VnQ+APT/x8uitkZsuRY9tmWcHK8/zWTc1GpFdwGUJ9+Yzvprtej+P/buxM9J +Y6ZJZdCIHWDuh3eq+sXS4lwr5fi7ir5m97npG1bXPlOoYIJ7p172EyoNmurRIgiP +LWnzK0jG/wKBgQCRQtOouNFFcyZLaTCPutxdRddy7ESRrRq0eOax9pVH6tw12URy +snyk3naqepdwYG6li82zsSKig8nA/0uktDeyVwoLjhpiwbc7KZc1sxaI7o4/US1B +McBb0G/MqH0elz4myxnomP8BHhOhLflmvnZexrqCbFyJvk8PFFn7aUWMCQKBgDvX +9BCzOszYJqh94X9NrQapqJxu1u6mZFelhjRBHARTgQ0MqC8IS0R58UjNTBeqj5Re +mdCDHar/gSHW3qkBzPPEhMlsXol5TZjzqp5cT7sA5uicDwowmxpVgCwVVeBFQG0n +fDAmtCIGz/A2uQ5YIRQuMzr6VZJAGUgLndQtlfd7AoGBAMq1imggFKd1rt49XCnO +t97lpWOT+TlWYblHr01tOw+esawG5MFucqVI6tGpBSccTRQw6orWf4GK3KmkgQ6J +UgHKjwYsA0sf4U5vppkdkbAbM/WwUPOTQpGFRERyJqMqFGIc4wMtZOJBxXwf+9iD +l8tvan8w/6HugqnI7qqkTgLq -----END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/ca.pem b/src/core/tsi/test_creds/ca.pem index 6c8511a73c6..49d39cd8ed5 100644 --- a/src/core/tsi/test_creds/ca.pem +++ b/src/core/tsi/test_creds/ca.pem @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= +MIIDWjCCAkKgAwIBAgIUWrP0VvHcy+LP6UuYNtiL9gBhD5owDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxNzE4NTk1MVoXDTMwMDMxNTE4NTk1MVowVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsGL0oXflF0LzoM+Bh+qUU9yhqzw2w8OOX5mu/iNCyUOBrqaHi7mGHx73GD01 +diNzCzvlcQqdNIH6NQSL7DTpBjca66jYT9u73vZe2MDrr1nVbuLvfu9850cdxiUO +Inv5xf8+sTHG0C+a+VAvMhsLiRjsq+lXKRJyk5zkbbsETybqpxoJ+K7CoSy3yc/k +QIY3TipwEtwkKP4hzyo6KiGd/DPexie4nBUInN3bS1BUeNZ5zeaIC2eg3bkeeW7c +qT55b+Yen6CxY0TEkzBK6AKt/WUialKMgT0wbTxRZO7kUCH3Sq6e/wXeFdJ+HvdV +LPlAg5TnMaNpRdQih/8nRFpsdwIDAQABoyAwHjAMBgNVHRMEBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAkTrKZjBrJXHps/HrjNCFPb5a +THuGPCSsepe1wkKdSp1h4HGRpLoCgcLysCJ5hZhRpHkRihhef+rFHEe60UePQO3S +CVTtdJB4CYWpcNyXOdqefrbJW5QNljxgi6Fhvs7JJkBqdXIkWXtFk2eRgOIP2Eo9 +/OHQHlYnwZFrk6sp4wPyR+A95S0toZBcyDVz7u+hOW0pGK3wviOe9lvRgj/H3Pwt +bewb0l+MhRig0/DVHamyVxrDRbqInU1/GTNCwcZkXKYFWSf92U+kIcTth24Q1gcw +eZiLl5FfrWokUNytFElXob0V0a5/kbhiLc3yWmvWqHTpqCALbVyF+rKJo2f5Kw== -----END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/client.key b/src/core/tsi/test_creds/client.key index f48d0735d99..349b40033dd 100644 --- a/src/core/tsi/test_creds/client.key +++ b/src/core/tsi/test_creds/client.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOxUR9uhvhbeVUIM -s5WbH0px0mehl2+6sZpNjzvE2KimZpHzMJHukVH0Ffkvhs0b8+S5Ut9VNUAqd3IM -JCCAEGtRNoQhM1t9Yr2zAckSvbRacp+FL/Cj9eDmyo00KsVGaeefA4Dh4OW+ZhkT -NKcldXqkSuj1sEf244JZYuqZp6/tAgMBAAECgYEAi2NSVqpZMafE5YYUTcMGe6QS -k2jtpsqYgggI2RnLJ/2tNZwYI5pwP8QVSbnMaiF4gokD5hGdrNDfTnb2v+yIwYEH -0w8+oG7Z81KodsiZSIDJfTGsAZhVNwOz9y0VD8BBZZ1/274Zh52AUKLjZS/ZwIbS -W2ywya855dPnH/wj+0ECQQD9X8D920kByTNHhBG18biAEZ4pxs9f0OAG8333eVcI -w2lJDLsYDZrCB2ocgA3lUdozlzPC7YDYw8reg0tkiRY5AkEA7sdNzOeQsQRn7++5 -0bP9DtT/iON1gbfxRzCfCfXdoOtfQWIzTePWtURt9X/5D9NofI0Rg5W2oGy/MLe5 -/sXHVQJBAIup5XrJDkQywNZyAUU2ecn2bCWBFjwtqd+LBmuMciI9fOKsZtEKZrz/ -U0lkeMRoSwvXE8wmGLjjrAbdfohrXFkCQQDZEx/LtIl6JINJQiswVe0tWr6k+ASP -1WXoTm+HYpoF/XUvv9LccNF1IazFj34hwRQwhx7w/V52Ieb+p0jUMYGxAkEAjDhd -9pBO1fKXWiXzi9ZKfoyTNcUq3eBSVKwPG2nItg5ycXengjT5sgcWDnciIzW7BIVI -JiqOszq9GWESErAatg== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyqYRp+DXVp72N +FbQH8hdhTZLycZXOlJhmMsrJmrjn2p7pI/8mTZ/0FC+SGWBGZV+ELiHrmCX5zfaI +Lr9Iuw7Ghr3Vzoefi8r62rLupVPNi/qdqyjWk2dECHC9Z3+Ag3KzKTyerXWjKcvy +KVmM0ZxE0RXhDW/RoQbqZsU2GKg1B2rhUU8KN0gVmKn0rJHOxzRVSYeYLYp5Yn7K +rtPJcKyo9aVuEr7dGANzpyF6lg/nYBWc+9SGwkoLdFvKvABYJMyrbNhHUQfv0fza +Z0P86dfTENrDxzALrzGnqcx3KTrwJjkZ/aSr1tyD0/tXvukRFiPxWBJhjHQ70GqT +FQY19RbhAgMBAAECggEAIL8JUhL4awyvpWhQ8xPgTSlWwbEn8BE0TacJnCILuhNM +BRdf8LlRk/8PKQwVpVF3TFbYSMI+U6b4hMVssfv3HVQc/083dHq+3XOwUCVlUstR +SAzTE2E5EDMr1stdh0SQhV4Nilfos9s5Uk1Z6IGSztoz1GgOErIc/mGPy/aA/hbr +fRWHvTp35+MbCJSvZuOeevX2iLs0dNzqdk6DiOWIH/BVGirVPtO6ykrkuTj1FWiN +hyZ3MBChShlNH2poNX46ntOc7nEus0qteOgxBK8lummFEtlehCA7hd/8xuvYlP0k +7aN684LCRDajmAGpoZO57NSDYQhAFGZeUZ93SMFucQKBgQDe7GGkzZFEiv91u1q9 +lgMy1h5dZjIZKgQaOarPC6wCQMUdqCf6cSLsAPr4T8EDoWsnY7dSnrTZ6YCIFL1T +idg8M3BQXipICCJkFORS76pKKZ0wMn3/NgkSepsmNct91WHr6okvx4tOaoRCtdzU +g7jt4Mr3sfLCiZtqTQyySdMUEwKBgQDNK+ZFKL0XhkWZP+PGKjWG8LWpPiK3d78/ +wYBFXzSTGlkr6FvRmYtZeNwXWRYLB4UxZ9At4hbJVEdi/2dITOz/sehVDyCAjjs3 +gycsc3UJqiZbcw5XKhI5TWBuWxkKENdbMSayogVbp2aSYoRblH764//t0ACmbfTW +KUQRQPB/uwKBgQC5QjjjfPL8w4cJkGoYpFKELO2PMR7xSrmeEc6hwlFwjeNCgjy3 +JM6g0y++rIj7O2qRkY0IXFxvvF3UuWedxTCu1xC/uYHp2ti506LsScB7YZoAM/YB +4iYn9Tx6xLoYGP0H0iGwU2SyBlNkHT8oXU+SYP5MWtYkVbeS3/VtNWz1gQKBgQCA +6Nk4kN0mH7YxEKRzSOfyzeDF4oV7kuB2FYUbkTL+TirC3K58JiYY5Egc31trOKFm +Jlz1xz0b6DkmKWTiV3r9OPHKJ8P7IeJxAZWmZzCdDuwkv0i+WW+z0zsIe3JjEavN +3zb6O7R0HtziksWoqMeTqZeO+wa9iw6vVKQw1wWEqwKBgFHfahFs0DZ5cUTpGpBt +F/AQG7ukgipB6N6AkB9kDbgCs1FLgd199MQrEncug5hfpq8QerbyMatmA+GXoGMb +7vztKEH85yzp4n02FNL6H7xL4VVILvyZHdolmiORJ4qT2hZnl8pEQ2TYuF4RlHUd +nSwXX+2o0J/nF85fm4AwWKAc -----END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/client.pem b/src/core/tsi/test_creds/client.pem index e332091019b..8815875f327 100644 --- a/src/core/tsi/test_creds/client.pem +++ b/src/core/tsi/test_creds/client.pem @@ -1,14 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICHzCCAYgCAQEwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV -BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 -ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcxNzIzNTYwMloXDTI0MDcxNDIzNTYw -MlowWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKdGVzdGNsaWVudDCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7FRH26G+Ft5VQgyzlZsfSnHSZ6GX -b7qxmk2PO8TYqKZmkfMwke6RUfQV+S+GzRvz5LlS31U1QCp3cgwkIIAQa1E2hCEz -W31ivbMByRK9tFpyn4Uv8KP14ObKjTQqxUZp558DgOHg5b5mGRM0pyV1eqRK6PWw -R/bjglli6pmnr+0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAStSm5PM7ubROiKK6/ -T2FkKlhiTOx+Ryenm3Eio59emq+jXl+1nhPySX5G2PQzSR5vd1dIhwgZSR4Gyttk -tRZ57k/NI1brUW8joiEOMJA/Mr7H7asx7wIRYDE91Fs8GkKWd5LhoPAQj+qdG35C -OO+svdkmqH0KZo320ZUqdl2ooQ== +MIIDNzCCAh8CFGyX00RCepOv/qCJ1oVdTtY92U83MA0GCSqGSIb3DQEBCwUAMFYx +CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMDAzMTgw +MTA2MTBaFw0zMDAzMTYwMTA2MTBaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApT +b21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzAR +BgNVBAMMCnRlc3RjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCyqYRp+DXVp72NFbQH8hdhTZLycZXOlJhmMsrJmrjn2p7pI/8mTZ/0FC+SGWBG +ZV+ELiHrmCX5zfaILr9Iuw7Ghr3Vzoefi8r62rLupVPNi/qdqyjWk2dECHC9Z3+A +g3KzKTyerXWjKcvyKVmM0ZxE0RXhDW/RoQbqZsU2GKg1B2rhUU8KN0gVmKn0rJHO +xzRVSYeYLYp5Yn7KrtPJcKyo9aVuEr7dGANzpyF6lg/nYBWc+9SGwkoLdFvKvABY +JMyrbNhHUQfv0fzaZ0P86dfTENrDxzALrzGnqcx3KTrwJjkZ/aSr1tyD0/tXvukR +FiPxWBJhjHQ70GqTFQY19RbhAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFXCewK8 +cWT+zWxXyGFnouFSBzTi0BMBJRrhsiNoiQxkqityJHWFExiQZie+7CA+EabXCQUB ++JwMSWM29j3mSw10DTfmC3rhheQqGxy304BZyUpdpvI2dt3p/mcsE7O+p4sQrSep +gijiDssKAfxTAmUM93N6+Q8yJK5immxlbeYfijoBvmkzyB/B+qNRPsx0n7aFGnfv +oWfkW296iPhWLiwknpC3xB6oK3vRbK4Zj1OaGb0grK7VN8EyhBix2xVF61i4dzCK +kMIpl7CUpw1Mb2z8q3F2bHBS7iF7g1Ccn5VGcO+aJ+6PWydaeqJ6VEBF0Nwv9woe +mL5AluNRLaqjZvE= -----END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/server0.key b/src/core/tsi/test_creds/server0.key index add153c9aea..261097a87e3 100644 --- a/src/core/tsi/test_creds/server0.key +++ b/src/core/tsi/test_creds/server0.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANOmffupIGC8YDau -rOF4eKnHwPszgpkkhWzKsVxhNDBxCVYx4TEjG0XWIO0iyRXupZbUC+7N/8HnEVNa -8F1jYhng14Iiq99cNQbbnuHHhIztmpocrJTxmnhGzoAnRa1Tb+GnAuRoIHRA/V2c -VUE9tbikQugFx/SPgXAw6tfWB+YvAgMBAAECgYEAoEq9qzUBgoHoVEGiSPiWWe8g -5p6yUA1qx2QTQyWTAwT4z0DjjfVKmG99bFsl8+hTnJFnoCp/gnjflEOROwkjp5kG -m0drqOPx1jeipJjpXYTBu49h+WpZ1PF+KhVtxsIm3OOCvh67iWaKyyOVb5Og8aiR -jl6dn/TdG/dlGD8AfUECQQDuNMle6p0oU8amC6O9wIMBroxx2nFstzE6O35PLEzG -/tj0kxxn9Jp2TS9mGaLCzSuXmpjlF4+NOWiBPkrLC2TfAkEA43Xg7uEUkaJAz2/W -m1lIBTLt+4rIQY/2emh33bDcA+rv8rwwrMMIv17/xPx7bs49YqGG5xufD+Rwl6TL -qFXYsQJAPrOwagax1aKvwJeBw3oAQhoTKAkLIEXcdGqipe6QSzVcIIz0xjxxyEAr -AOIwoLxnBCISqwMXq2H4K0UdZPMb2wJAdhdYLY1L6YRMk6XjzImg25oidisKZweA -FvMv8DgHMj2CUAqmVrt3SivfLH1M9C09L3zfFhOAFHcsgX58gav4MQJBANSBnrHj -tIq4l8z79CPUIuu3QyeEh+XwY8s5qE5CNTck0U59lzp9NvENHbkx3KO896TTerko -+8bXHMLkJkHPXms= +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCei9aKutDNg2mr +COICW4hT6+LVJfI5J6DZ3yqb6MBzbc//VeUj1OCX/vt5vvPm1Qb5XNk1MOIFPEW6 +t2/0Mhj2VbQfjDe/PhZRhwu4PBtuoJBDeBsKkdnxD0I+4G0XRbeTtUsGMGBgWSAd +qHMD2HnEhgydRw0krYjZp4a/HMCnZZ1WFamw1PCvQK6AuWSSk4iHGaYklXUaKd3r +Rlkujr7//ihcvqweJ+OdaTwXD8z4P0YfFe/bkWWpuqIZz1Or/nxiNBtvWKlI8pR2 +K3wkoWsW+6bnFN8u81nstHDardR6zy3B7QXke02q4sddUERcwNFyPqpscetMpnhg +lhjrmnAXAgMBAAECggEAA6pB5GUbLJUMHUsQRnOtPBto2/qLleynmEHDb2U7BbAV +LdbjfCeQpZLcZ10VsFFeXudZkhQ2NV7GUeGpseBymUcz6cLJCx+5Tlsr1y90huMp +UpX1MhJbEmqC4oc3nmEbNEvtlxAJOlD1IBpjxkP71KIwqnYZBK8KSdXIlKRqg7QZ +VUgjA08TmWlZSxnOt1hpt2ZVjTOn7973YoTb4D7SZydMuVjTkwv9YjPFZOZ/wIP4 +JTZczY/bJjEF7QBYL/wtir/vNJlxxi+FunJdoO3blhf8li5QU0iPd/YsyBFBBWfF +vD7QslaB7wQ8zyWxWpPLiWeD83XGE+7CY2+8EpG3AQKBgQDMK6N7jDQCq9F7n+5B +R8YPDMdINpcVsN8bIeEVKSxYE86oADQg/0jPUct+4liUS1dv0DUmUP1U0zbvupX7 +NxE+gI8KFwCyq8nqZ1guW9oO00ZAGo4Rn0TIeoHWVgsE2tDqBFeC2wWYle1AaZLx +ZtFH6Ya4Q3a4xvjkXXabhbBDlwKBgQDGyzuNCGT1Xa1DXKLzyKspahdm9r7QXifo +jjZkcmzwItC535MBbQMq5+THD+WUbWrZ/rJ8KaSsoGmnjaWguSG0WLFpH3UiGn1W +FOSG2UGc0mWyz2p/j97EuhK12fabzn8rkuiohiFXjJDYrAIulcM++0ar3q2LyqXr +gleBEHLHgQKBgEAt44j9rIe+bO44etOIdUjb0nTvvBR0cd18i910AN169HY5Ainx +NXj+FELBcejDuiuKvnpZ8RhOALHg7C54w/HqxYv9aRnBCIqni7+e3e/VF/sknc4K +S7vdTp0KlRIkmpFFZiDbKmopjte1mBxMHrNFRDT99/7jhO98NcFzh9HnAoGAMf62 +sVdlHJg8lO5dRPY4pae6zvhLMNgdLU1mvIhSgWogGD70F6202DuNu8pxsIx8DOsT +NEq80XVeXPcwqmUk5thPdeKlcLg8wUNr3cYRzEDVtsyXOhGSsuMhBX8VmEWskebW +gFuLUxtU6kkIG3MqsVI8icjs2HVUmRAktZ7PXwECgYA9V/zZe2DpP36gp63wRk6S +FI7bDbLPQCKah23mwp3WeP5T+/HmFFRrl0OCaDLwudTolqgPa47CV7JYa9LmJAPj +QBxcnL4CxjlaaS3V9kxVWOXabMEtwSUurELJwFKTEC/AFN9dR/nv4AzXInZznotG +7qDX8EhfjbFVJw4riAmlEw== -----END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/server0.pem b/src/core/tsi/test_creds/server0.pem index ade75d8563f..ab20787fa5b 100644 --- a/src/core/tsi/test_creds/server0.pem +++ b/src/core/tsi/test_creds/server0.pem @@ -1,14 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICHDCCAYUCAQQwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV -BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 -ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcyMjE3NTk0OVoXDTI0MDcxOTE3NTk0 -OVowVzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxFDASBgNVBAoM -C0dvb2dsZSBJbmMuMR0wGwYDVQQDDBQqLnRlc3QuZ29vZ2xlLmNvbS5hdTCBnzAN -BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06Z9+6kgYLxgNq6s4Xh4qcfA+zOCmSSF -bMqxXGE0MHEJVjHhMSMbRdYg7SLJFe6lltQL7s3/wecRU1rwXWNiGeDXgiKr31w1 -Btue4ceEjO2amhyslPGaeEbOgCdFrVNv4acC5GggdED9XZxVQT21uKRC6AXH9I+B -cDDq19YH5i8CAwEAATANBgkqhkiG9w0BAQUFAAOBgQBtfR5qXG9TTI8YcYh7sA4V -GeNoplp0x6p7OG0NLvbJqAkUnkvjIkk1m1R2AUHhbkxzx6G75JIOoNJcWrCzywBA -BIsaTdmnNysf/s1hQJuD3IHiVb+7Ji0jhttnJlYcMid4o0tJO/a2E9YUxR+9cg0i -obb+Ql3qsvKdWBC1dDLDLw== +MIIDQTCCAikCFGyX00RCepOv/qCJ1oVdTtY92U84MA0GCSqGSIb3DQEBCwUAMFYx +CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMDAzMTgw +MTA3MzhaFw0zMDAzMTYwMTA3MzhaMGQxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApT +b21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxHTAb +BgNVBAMMFCoudGVzdC5nb29nbGUuY29tLmF1MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnovWirrQzYNpqwjiAluIU+vi1SXyOSeg2d8qm+jAc23P/1Xl +I9Tgl/77eb7z5tUG+VzZNTDiBTxFurdv9DIY9lW0H4w3vz4WUYcLuDwbbqCQQ3gb +CpHZ8Q9CPuBtF0W3k7VLBjBgYFkgHahzA9h5xIYMnUcNJK2I2aeGvxzAp2WdVhWp +sNTwr0CugLlkkpOIhxmmJJV1Gind60ZZLo6+//4oXL6sHifjnWk8Fw/M+D9GHxXv +25FlqbqiGc9Tq/58YjQbb1ipSPKUdit8JKFrFvum5xTfLvNZ7LRw2q3Ues8twe0F +5HtNquLHXVBEXMDRcj6qbHHrTKZ4YJYY65pwFwIDAQABMA0GCSqGSIb3DQEBCwUA +A4IBAQCCGvZpM+t83xWPCsz5FyuCqA6LI+j0NMMmKpe1wJ8JcK2o9Qw4d0wPxWdy +0O7Ti2YlJS3gups00zsaFhQymIKUBi5Gc+1VC7qHUUrVtkoIRe6QSpcVlxPVczlD +If1egkjBCUZKVSWqYRKB6AMqjpp7/dF06j6zAaAH54jaLv9VmiBtsFyd017AsC9W ++OG2ke2dNtXySfVX4VusCcji86qb5sr6hNIQWMXk6dZoLDsZvwvVi7KnrqQOza8J +klcJXV8Hsnq/faHr/ZmsIA65N0+H8KuYfbO+s5nKPG9th6ZZAu4aY2VDei++TH+H +EAQhivPNUC1DgCmx0P7vKLhgka7S -----END CERTIFICATE----- diff --git a/src/core/tsi/test_creds/server1.key b/src/core/tsi/test_creds/server1.key index 143a5b87658..086462992cf 100644 --- a/src/core/tsi/test_creds/server1.key +++ b/src/core/tsi/test_creds/server1.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnE443EknxvxBq +6+hvn/t09hl8hx366EBYvZmVM/NC+7igXRAjiJiA/mIaCvL3MS0Iz5hBLxSGICU+ +WproA3GCIFITIwcf/ETyWj/5xpgZ4AKrLrjQmmX8mhwUajfF3UvwMJrCOVqPp67t +PtP+2kBXaqrXdvnvXR41FsIB8V7zIAuIZB6bHQhiGVlc1sgZYsE2EGG9WMmHtS86 +qkAOTjG2XyjmPTGAwhGDpYkYrpzp99IiDh4/Veai81hn0ssQkbry0XRD/Ig3jcHh +23WiriPNJ0JsbgXUSLKRPZObA9VgOLy2aXoN84IMaeK3yy+cwSYG/99w93fUZJte +MXwz4oYZAgMBAAECggEBAIVn2Ncai+4xbH0OLWckabwgyJ4IM9rDc0LIU368O1kU +koais8qP9dujAWgfoh3sGh/YGgKn96VnsZjKHlyMgF+r4TaDJn3k2rlAOWcurGlj +1qaVlsV4HiEzp7pxiDmHhWvp4672Bb6iBG+bsjCUOEk/n9o9KhZzIBluRhtxCmw5 +nw4Do7z00PTvN81260uPWSc04IrytvZUiAIx/5qxD72bij2xJ8t/I9GI8g4FtoVB +8pB6S/hJX1PZhh9VlU6Yk+TOfOVnbebG4W5138LkB835eqk3Zz0qsbc2euoi8Hxi +y1VGwQEmMQ63jXz4c6g+X55ifvUK9Jpn5E8pq+pMd7ECgYEA93lYq+Cr54K4ey5t +sWMa+ye5RqxjzgXj2Kqr55jb54VWG7wp2iGbg8FMlkQwzTJwebzDyCSatguEZLuB +gRGroRnsUOy9vBvhKPOch9bfKIl6qOgzMJB267fBVWx5ybnRbWN/I7RvMQf3k+9y +biCIVnxDLEEYyx7z85/5qxsXg/MCgYEA7wmWKtCTn032Hy9P8OL49T0X6Z8FlkDC +Rk42ygrc/MUbugq9RGUxcCxoImOG9JXUpEtUe31YDm2j+/nbvrjl6/bP2qWs0V7l +dTJl6dABP51pCw8+l4cWgBBX08Lkeen812AAFNrjmDCjX6rHjWHLJcpS18fnRRkP +V1d/AHWX7MMCgYEA6Gsw2guhp0Zf2GCcaNK5DlQab8OL4Hwrpttzo4kuTlwtqNKp +Q9H4al9qfF4Cr1TFya98+EVYf8yFRM3NLNjZpe3gwYf2EerlJj7VLcahw0KKzoN1 +QBENfwgPLRk5sDkx9VhSmcfl/diLroZdpAwtv3vo4nEoxeuGFbKTGx3Qkf0CgYEA +xyR+dcb05Ygm3w4klHQTowQ10s1H80iaUcZBgQuR1ghEtDbUPZHsoR5t1xCB02ys +DgAwLv1bChIvxvH/L6KM8ovZ2LekBX4AviWxoBxJnfz/EVau98B0b1auRN6eSC83 +FRuGldlSOW1z/nSh8ViizSYE5H5HX1qkXEippvFRE88CgYB3Bfu3YQY60ITWIShv +nNkdcbTT9eoP9suaRJjw92Ln+7ZpALYlQMKUZmJ/5uBmLs4RFwUTQruLOPL4yLTH +awADWUzs3IRr1fwn9E+zM8JVyKCnUEM3w4N5UZskGO2klashAd30hWO+knRv/y0r +uGIYs9Ek7YXlXIRVrzMwcsrt1w== -----END PRIVATE KEY----- diff --git a/src/core/tsi/test_creds/server1.pem b/src/core/tsi/test_creds/server1.pem index f3d43fcc5be..88244f856c6 100644 --- a/src/core/tsi/test_creds/server1.pem +++ b/src/core/tsi/test_creds/server1.pem @@ -1,16 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 +MIIDtDCCApygAwIBAgIUbJfTREJ6k6/+oInWhV1O1j3ZT0IwDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxODAzMTA0MloXDTMwMDMxNjAzMTA0MlowZTELMAkGA1UEBhMCVVMxETAPBgNV +BAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxl +LCBDby4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5xOONxJJ8b8Qauvob5/7dPYZfIcd+uhAWL2ZlTPz +Qvu4oF0QI4iYgP5iGgry9zEtCM+YQS8UhiAlPlqa6ANxgiBSEyMHH/xE8lo/+caY +GeACqy640Jpl/JocFGo3xd1L8DCawjlaj6eu7T7T/tpAV2qq13b5710eNRbCAfFe +8yALiGQemx0IYhlZXNbIGWLBNhBhvVjJh7UvOqpADk4xtl8o5j0xgMIRg6WJGK6c +6ffSIg4eP1XmovNYZ9LLEJG68tF0Q/yIN43B4dt1oq4jzSdCbG4F1EiykT2TmwPV +YDi8tml6DfOCDGnit8svnMEmBv/fcPd31GSbXjF8M+KGGQIDAQABo2swaTAJBgNV +HRMEAjAAMAsGA1UdDwQEAwIF4DBPBgNVHREESDBGghAqLnRlc3QuZ29vZ2xlLmZy +ghh3YXRlcnpvb2kudGVzdC5nb29nbGUuYmWCEioudGVzdC55b3V0dWJlLmNvbYcE +wKgBAzANBgkqhkiG9w0BAQsFAAOCAQEAS8hDQA8PSgipgAml7Q3/djwQ644ghWQv +C2Kb+r30RCY1EyKNhnQnIIh/OUbBZvh0M0iYsy6xqXgfDhCB93AA6j0i5cS8fkhH +Jl4RK0tSkGQ3YNY4NzXwQP/vmUgfkw8VBAZ4Y4GKxppdATjffIW+srbAmdDruIRM +wPeikgOoRrXf0LA1fi4TqxARzeRwenQpayNfGHTvVF9aJkl8HoaMunTAdG5pIVcr +9GKi/gEMpXUJbbVv3U5frX1Wo4CFo+rZWJ/LyCMeb0jciNLxSdMwj/E/ZuExlyeZ +gc9ctPjSMvgSyXEKv6Vwobleeg88V2ZgzenziORoWj4KszG/lbQZvg== -----END CERTIFICATE----- diff --git a/src/cpp/README.md b/src/cpp/README.md index 96ea8074fcf..3f1d4a6fcf8 100755 --- a/src/cpp/README.md +++ b/src/cpp/README.md @@ -157,12 +157,12 @@ You can find out how to build and run our simplest gRPC C++ example in our For more detailed documentation on using gRPC in C++ , see our main documentation site at [grpc.io](https://grpc.io), specifically: -* [Overview](https://grpc.io/docs/): An introduction to gRPC with a simple +* [Overview](https://grpc.io/docs): An introduction to gRPC with a simple Hello World example in all our supported languages, including C++. -* [gRPC Basics - C++](https://grpc.io/docs/tutorials/basic/c.html): +* [gRPC Basics - C++](https://grpc.io/docs/tutorials/basic/cpp): A tutorial that steps you through creating a simple gRPC C++ example application. -* [Asynchronous Basics - C++](https://grpc.io/docs/tutorials/async/helloasync-cpp.html): +* [Asynchronous Basics - C++](https://grpc.io/docs/tutorials/async/helloasync-cpp): A tutorial that shows you how to use gRPC C++'s asynchronous/non-blocking APIs. diff --git a/src/cpp/common/tls_credentials_options.cc b/src/cpp/common/tls_credentials_options.cc index d2abe2128c3..c821e100f93 100644 --- a/src/cpp/common/tls_credentials_options.cc +++ b/src/cpp/common/tls_credentials_options.cc @@ -68,8 +68,7 @@ grpc_ssl_certificate_config_reload_status TlsCredentialReloadArg::status() } grpc::string TlsCredentialReloadArg::error_details() const { - grpc::string cpp_error_details(c_arg_->error_details); - return cpp_error_details; + return c_arg_->error_details->error_details(); } void TlsCredentialReloadArg::set_cb_user_data(void* cb_user_data) { @@ -159,7 +158,7 @@ void TlsCredentialReloadArg::set_status( void TlsCredentialReloadArg::set_error_details( const grpc::string& error_details) { - c_arg_->error_details = gpr_strdup(error_details.c_str()); + c_arg_->error_details->set_error_details(error_details.c_str()); } void TlsCredentialReloadArg::OnCredentialReloadDoneCallback() { @@ -221,8 +220,7 @@ grpc_status_code TlsServerAuthorizationCheckArg::status() const { } grpc::string TlsServerAuthorizationCheckArg::error_details() const { - grpc::string cpp_error_details(c_arg_->error_details); - return cpp_error_details; + return c_arg_->error_details->error_details(); } void TlsServerAuthorizationCheckArg::set_cb_user_data(void* cb_user_data) { @@ -254,7 +252,7 @@ void TlsServerAuthorizationCheckArg::set_status(grpc_status_code status) { void TlsServerAuthorizationCheckArg::set_error_details( const grpc::string& error_details) { - c_arg_->error_details = gpr_strdup(error_details.c_str()); + c_arg_->error_details->set_error_details(error_details.c_str()); } void TlsServerAuthorizationCheckArg::OnServerAuthorizationCheckDoneCallback() { diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 34ffd59489f..a30e4911dc0 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -1241,6 +1241,12 @@ void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) { RegisterCallbackGenericService(unimplemented_service_.get()); } +#ifndef NDEBUG + for (size_t i = 0; i < num_cqs; i++) { + cq_list_.push_back(cqs[i]); + } +#endif + grpc_server_start(server_); if (!has_async_generic_service_ && !has_callback_generic_service_) { @@ -1249,9 +1255,6 @@ void Server::Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) { } for (size_t i = 0; i < num_cqs; i++) { -#ifndef NDEBUG - cq_list_.push_back(cqs[i]); -#endif if (cqs[i]->IsFrequentlyPolled()) { new UnimplementedAsyncRequest(this, cqs[i]); } diff --git a/src/csharp/Grpc.IntegrationTesting/data/ca.pem b/src/csharp/Grpc.IntegrationTesting/data/ca.pem index 6c8511a73c6..49d39cd8ed5 100644 --- a/src/csharp/Grpc.IntegrationTesting/data/ca.pem +++ b/src/csharp/Grpc.IntegrationTesting/data/ca.pem @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= +MIIDWjCCAkKgAwIBAgIUWrP0VvHcy+LP6UuYNtiL9gBhD5owDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxNzE4NTk1MVoXDTMwMDMxNTE4NTk1MVowVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsGL0oXflF0LzoM+Bh+qUU9yhqzw2w8OOX5mu/iNCyUOBrqaHi7mGHx73GD01 +diNzCzvlcQqdNIH6NQSL7DTpBjca66jYT9u73vZe2MDrr1nVbuLvfu9850cdxiUO +Inv5xf8+sTHG0C+a+VAvMhsLiRjsq+lXKRJyk5zkbbsETybqpxoJ+K7CoSy3yc/k +QIY3TipwEtwkKP4hzyo6KiGd/DPexie4nBUInN3bS1BUeNZ5zeaIC2eg3bkeeW7c +qT55b+Yen6CxY0TEkzBK6AKt/WUialKMgT0wbTxRZO7kUCH3Sq6e/wXeFdJ+HvdV +LPlAg5TnMaNpRdQih/8nRFpsdwIDAQABoyAwHjAMBgNVHRMEBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAkTrKZjBrJXHps/HrjNCFPb5a +THuGPCSsepe1wkKdSp1h4HGRpLoCgcLysCJ5hZhRpHkRihhef+rFHEe60UePQO3S +CVTtdJB4CYWpcNyXOdqefrbJW5QNljxgi6Fhvs7JJkBqdXIkWXtFk2eRgOIP2Eo9 +/OHQHlYnwZFrk6sp4wPyR+A95S0toZBcyDVz7u+hOW0pGK3wviOe9lvRgj/H3Pwt +bewb0l+MhRig0/DVHamyVxrDRbqInU1/GTNCwcZkXKYFWSf92U+kIcTth24Q1gcw +eZiLl5FfrWokUNytFElXob0V0a5/kbhiLc3yWmvWqHTpqCALbVyF+rKJo2f5Kw== -----END CERTIFICATE----- diff --git a/src/csharp/Grpc.IntegrationTesting/data/server1.key b/src/csharp/Grpc.IntegrationTesting/data/server1.key index 143a5b87658..086462992cf 100644 --- a/src/csharp/Grpc.IntegrationTesting/data/server1.key +++ b/src/csharp/Grpc.IntegrationTesting/data/server1.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnE443EknxvxBq +6+hvn/t09hl8hx366EBYvZmVM/NC+7igXRAjiJiA/mIaCvL3MS0Iz5hBLxSGICU+ +WproA3GCIFITIwcf/ETyWj/5xpgZ4AKrLrjQmmX8mhwUajfF3UvwMJrCOVqPp67t +PtP+2kBXaqrXdvnvXR41FsIB8V7zIAuIZB6bHQhiGVlc1sgZYsE2EGG9WMmHtS86 +qkAOTjG2XyjmPTGAwhGDpYkYrpzp99IiDh4/Veai81hn0ssQkbry0XRD/Ig3jcHh +23WiriPNJ0JsbgXUSLKRPZObA9VgOLy2aXoN84IMaeK3yy+cwSYG/99w93fUZJte +MXwz4oYZAgMBAAECggEBAIVn2Ncai+4xbH0OLWckabwgyJ4IM9rDc0LIU368O1kU +koais8qP9dujAWgfoh3sGh/YGgKn96VnsZjKHlyMgF+r4TaDJn3k2rlAOWcurGlj +1qaVlsV4HiEzp7pxiDmHhWvp4672Bb6iBG+bsjCUOEk/n9o9KhZzIBluRhtxCmw5 +nw4Do7z00PTvN81260uPWSc04IrytvZUiAIx/5qxD72bij2xJ8t/I9GI8g4FtoVB +8pB6S/hJX1PZhh9VlU6Yk+TOfOVnbebG4W5138LkB835eqk3Zz0qsbc2euoi8Hxi +y1VGwQEmMQ63jXz4c6g+X55ifvUK9Jpn5E8pq+pMd7ECgYEA93lYq+Cr54K4ey5t +sWMa+ye5RqxjzgXj2Kqr55jb54VWG7wp2iGbg8FMlkQwzTJwebzDyCSatguEZLuB +gRGroRnsUOy9vBvhKPOch9bfKIl6qOgzMJB267fBVWx5ybnRbWN/I7RvMQf3k+9y +biCIVnxDLEEYyx7z85/5qxsXg/MCgYEA7wmWKtCTn032Hy9P8OL49T0X6Z8FlkDC +Rk42ygrc/MUbugq9RGUxcCxoImOG9JXUpEtUe31YDm2j+/nbvrjl6/bP2qWs0V7l +dTJl6dABP51pCw8+l4cWgBBX08Lkeen812AAFNrjmDCjX6rHjWHLJcpS18fnRRkP +V1d/AHWX7MMCgYEA6Gsw2guhp0Zf2GCcaNK5DlQab8OL4Hwrpttzo4kuTlwtqNKp +Q9H4al9qfF4Cr1TFya98+EVYf8yFRM3NLNjZpe3gwYf2EerlJj7VLcahw0KKzoN1 +QBENfwgPLRk5sDkx9VhSmcfl/diLroZdpAwtv3vo4nEoxeuGFbKTGx3Qkf0CgYEA +xyR+dcb05Ygm3w4klHQTowQ10s1H80iaUcZBgQuR1ghEtDbUPZHsoR5t1xCB02ys +DgAwLv1bChIvxvH/L6KM8ovZ2LekBX4AviWxoBxJnfz/EVau98B0b1auRN6eSC83 +FRuGldlSOW1z/nSh8ViizSYE5H5HX1qkXEippvFRE88CgYB3Bfu3YQY60ITWIShv +nNkdcbTT9eoP9suaRJjw92Ln+7ZpALYlQMKUZmJ/5uBmLs4RFwUTQruLOPL4yLTH +awADWUzs3IRr1fwn9E+zM8JVyKCnUEM3w4N5UZskGO2klashAd30hWO+knRv/y0r +uGIYs9Ek7YXlXIRVrzMwcsrt1w== -----END PRIVATE KEY----- diff --git a/src/csharp/Grpc.IntegrationTesting/data/server1.pem b/src/csharp/Grpc.IntegrationTesting/data/server1.pem index f3d43fcc5be..88244f856c6 100644 --- a/src/csharp/Grpc.IntegrationTesting/data/server1.pem +++ b/src/csharp/Grpc.IntegrationTesting/data/server1.pem @@ -1,16 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 +MIIDtDCCApygAwIBAgIUbJfTREJ6k6/+oInWhV1O1j3ZT0IwDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxODAzMTA0MloXDTMwMDMxNjAzMTA0MlowZTELMAkGA1UEBhMCVVMxETAPBgNV +BAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxl +LCBDby4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5xOONxJJ8b8Qauvob5/7dPYZfIcd+uhAWL2ZlTPz +Qvu4oF0QI4iYgP5iGgry9zEtCM+YQS8UhiAlPlqa6ANxgiBSEyMHH/xE8lo/+caY +GeACqy640Jpl/JocFGo3xd1L8DCawjlaj6eu7T7T/tpAV2qq13b5710eNRbCAfFe +8yALiGQemx0IYhlZXNbIGWLBNhBhvVjJh7UvOqpADk4xtl8o5j0xgMIRg6WJGK6c +6ffSIg4eP1XmovNYZ9LLEJG68tF0Q/yIN43B4dt1oq4jzSdCbG4F1EiykT2TmwPV +YDi8tml6DfOCDGnit8svnMEmBv/fcPd31GSbXjF8M+KGGQIDAQABo2swaTAJBgNV +HRMEAjAAMAsGA1UdDwQEAwIF4DBPBgNVHREESDBGghAqLnRlc3QuZ29vZ2xlLmZy +ghh3YXRlcnpvb2kudGVzdC5nb29nbGUuYmWCEioudGVzdC55b3V0dWJlLmNvbYcE +wKgBAzANBgkqhkiG9w0BAQsFAAOCAQEAS8hDQA8PSgipgAml7Q3/djwQ644ghWQv +C2Kb+r30RCY1EyKNhnQnIIh/OUbBZvh0M0iYsy6xqXgfDhCB93AA6j0i5cS8fkhH +Jl4RK0tSkGQ3YNY4NzXwQP/vmUgfkw8VBAZ4Y4GKxppdATjffIW+srbAmdDruIRM +wPeikgOoRrXf0LA1fi4TqxARzeRwenQpayNfGHTvVF9aJkl8HoaMunTAdG5pIVcr +9GKi/gEMpXUJbbVv3U5frX1Wo4CFo+rZWJ/LyCMeb0jciNLxSdMwj/E/ZuExlyeZ +gc9ctPjSMvgSyXEKv6Vwobleeg88V2ZgzenziORoWj4KszG/lbQZvg== -----END CERTIFICATE----- diff --git a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets index b1030ba1f8b..ad6725f684a 100644 --- a/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets +++ b/src/csharp/Grpc.Tools/build/_protobuf/Google.Protobuf.Tools.targets @@ -137,7 +137,7 @@ %(RelativeDir) - + %(Identity) diff --git a/src/objective-c/README-CFSTREAM.md b/src/objective-c/README-CFSTREAM.md index 184d5679cbb..d4d26828534 100644 --- a/src/objective-c/README-CFSTREAM.md +++ b/src/objective-c/README-CFSTREAM.md @@ -1,7 +1,7 @@ [![Cocoapods](https://img.shields.io/cocoapods/v/gRPC.svg)](https://cocoapods.org/pods/gRPC) # gRPC Objective-C with CFStream -gRPC Objective-C library now provides the option to use Apple's CFStream API (rather than TCP +gRPC now provides the option to use Apple's CFStream API (rather than TCP sockets) for networking. Using CFStream resolves a bunch of network connectivity transition issues (see the [doc](https://github.com/grpc/grpc/blob/master/src/objective-c/NetworkTransitionBehavior.md) for more information). @@ -14,8 +14,11 @@ As of v1.21.0, CFStream integration is now the default networking stack being us Objective-C on iOS layer. You get to use it automatically without special configuration needed. See below on how to disable CFStream in case of problem. +As of v1.23.0, CFStream is enabled by default on iOS for all wrapped languages. See below on how to +disable CFStream in case of a problem. + ## Usage -If you use gRPC Objective-C library on iOS, CFStream is on automatically. If you use it on other +If you use gRPC on iOS, CFStream is on automatically. If you use it on other platforms, you can turn it on with macro `GRPC_CFSTREAM=1` for the pod 'gRPC-Core' and 'gRPC'. In case of problem and you want to disable CFStream on iOS, you can set environment variable "grpc\_cfstream=0". diff --git a/src/objective-c/tests/InteropTests/InteropTests.m b/src/objective-c/tests/InteropTests/InteropTests.m index 9c86a29373c..e2773984b15 100644 --- a/src/objective-c/tests/InteropTests/InteropTests.m +++ b/src/objective-c/tests/InteropTests/InteropTests.m @@ -39,6 +39,7 @@ #define TEST_TIMEOUT 32 +static const int kTestRetries = 3; extern const char *kCFStreamVarName; // Convenience constructors for the generated proto messages: @@ -382,6 +383,36 @@ static dispatch_once_t initGlobalInterceptorFactory; RMTTestService *_service; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +- (void)retriableTest:(SEL)selector retries:(int)retries timeout:(NSTimeInterval)timeout { + for (int i = 0; i < retries; i++) { + NSDate *waitUntil = [[NSDate date] dateByAddingTimeInterval:timeout]; + NSCondition *cv = [[NSCondition alloc] init]; + __block BOOL done = NO; + [cv lock]; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{ + [self performSelector:selector]; + [cv lock]; + done = YES; + [cv signal]; + [cv unlock]; + }); + while (!done && [waitUntil timeIntervalSinceNow] > 0) { + [cv waitUntilDate:waitUntil]; + } + if (done) { + [cv unlock]; + break; + } else { + [cv unlock]; + [self tearDown]; + [self setUp]; + } + } +} +#pragma clang diagnostic pop + + (XCTestSuite *)defaultTestSuite { if (self == [InteropTests class]) { return [XCTestSuite testSuiteWithName:@"InteropTestsEmptySuite"]; @@ -721,14 +752,13 @@ static dispatch_once_t initGlobalInterceptorFactory; [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; } -- (void)testConcurrentRPCsWithErrors { - NSMutableArray *completeExpectations = [NSMutableArray array]; - int num_rpcs = 10; - for (int i = 0; i < num_rpcs; ++i) { - [completeExpectations - addObject:[self expectationWithDescription: - [NSString stringWithFormat:@"Received trailer for RPC %d", i]]]; - +- (void)concurrentRPCsWithErrors { + const int kNumRpcs = 10; + __block int completedCallCount = 0; + NSCondition *cv = [[NSCondition alloc] init]; + NSDate *waitUntil = [[NSDate date] dateByAddingTimeInterval:TEST_TIMEOUT]; + [cv lock]; + for (int i = 0; i < kNumRpcs; ++i) { RMTSimpleRequest *request = [RMTSimpleRequest message]; request.responseType = RMTPayloadType_Compressable; request.responseSize = 314159; @@ -739,20 +769,33 @@ static dispatch_once_t initGlobalInterceptorFactory; request.responseStatus.code = GRPC_STATUS_CANCELLED; } - [_service unaryCallWithRequest:request - handler:^(RMTSimpleResponse *response, NSError *error) { - if (error == nil) { - RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; - expectedResponse.payload.type = RMTPayloadType_Compressable; - expectedResponse.payload.body = - [NSMutableData dataWithLength:314159]; - XCTAssertEqualObjects(response, expectedResponse); - } - [completeExpectations[i] fulfill]; - }]; + GRPCProtoCall *call = [_service + RPCToUnaryCallWithRequest:request + handler:^(RMTSimpleResponse *response, NSError *error) { + if (error == nil) { + RMTSimpleResponse *expectedResponse = [RMTSimpleResponse message]; + expectedResponse.payload.type = RMTPayloadType_Compressable; + expectedResponse.payload.body = [NSMutableData dataWithLength:314159]; + XCTAssertEqualObjects(response, expectedResponse); + } + // DEBUG + [cv lock]; + if (++completedCallCount == kNumRpcs) { + [cv signal]; + } + [cv unlock]; + }]; + [call setResponseDispatchQueue:dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL)]; + [call start]; + } + while (completedCallCount 0) { + [cv waitUntilDate:waitUntil]; } + [cv unlock]; +} - [self waitForExpectationsWithTimeout:TEST_TIMEOUT handler:nil]; +- (void)testConcurrentRPCsWithErrors { + [self retriableTest:@selector(concurrentRPCsWithErrors) retries:kTestRetries timeout:10]; } - (void)testPacketCoalescing { diff --git a/src/objective-c/tests/TestCertificates.bundle/test-certificates.pem b/src/objective-c/tests/TestCertificates.bundle/test-certificates.pem index 6c8511a73c6..49d39cd8ed5 100644 --- a/src/objective-c/tests/TestCertificates.bundle/test-certificates.pem +++ b/src/objective-c/tests/TestCertificates.bundle/test-certificates.pem @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= +MIIDWjCCAkKgAwIBAgIUWrP0VvHcy+LP6UuYNtiL9gBhD5owDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxNzE4NTk1MVoXDTMwMDMxNTE4NTk1MVowVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsGL0oXflF0LzoM+Bh+qUU9yhqzw2w8OOX5mu/iNCyUOBrqaHi7mGHx73GD01 +diNzCzvlcQqdNIH6NQSL7DTpBjca66jYT9u73vZe2MDrr1nVbuLvfu9850cdxiUO +Inv5xf8+sTHG0C+a+VAvMhsLiRjsq+lXKRJyk5zkbbsETybqpxoJ+K7CoSy3yc/k +QIY3TipwEtwkKP4hzyo6KiGd/DPexie4nBUInN3bS1BUeNZ5zeaIC2eg3bkeeW7c +qT55b+Yen6CxY0TEkzBK6AKt/WUialKMgT0wbTxRZO7kUCH3Sq6e/wXeFdJ+HvdV +LPlAg5TnMaNpRdQih/8nRFpsdwIDAQABoyAwHjAMBgNVHRMEBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAkTrKZjBrJXHps/HrjNCFPb5a +THuGPCSsepe1wkKdSp1h4HGRpLoCgcLysCJ5hZhRpHkRihhef+rFHEe60UePQO3S +CVTtdJB4CYWpcNyXOdqefrbJW5QNljxgi6Fhvs7JJkBqdXIkWXtFk2eRgOIP2Eo9 +/OHQHlYnwZFrk6sp4wPyR+A95S0toZBcyDVz7u+hOW0pGK3wviOe9lvRgj/H3Pwt +bewb0l+MhRig0/DVHamyVxrDRbqInU1/GTNCwcZkXKYFWSf92U+kIcTth24Q1gcw +eZiLl5FfrWokUNytFElXob0V0a5/kbhiLc3yWmvWqHTpqCALbVyF+rKJo2f5Kw== -----END CERTIFICATE----- diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4 index 7260dbc72ef..5600df34ccf 100755 --- a/src/php/ext/grpc/config.m4 +++ b/src/php/ext/grpc/config.m4 @@ -86,7 +86,7 @@ if test "$PHP_GRPC" != "no"; then PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c call_credentials.c channel.c \ channel_credentials.c completion_queue.c timeval.c server.c \ - server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11) + server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11 -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1) fi if test "$PHP_COVERAGE" = "yes"; then diff --git a/src/php/tests/data/ca.pem b/src/php/tests/data/ca.pem index 6c8511a73c6..49d39cd8ed5 100755 --- a/src/php/tests/data/ca.pem +++ b/src/php/tests/data/ca.pem @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= +MIIDWjCCAkKgAwIBAgIUWrP0VvHcy+LP6UuYNtiL9gBhD5owDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxNzE4NTk1MVoXDTMwMDMxNTE4NTk1MVowVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsGL0oXflF0LzoM+Bh+qUU9yhqzw2w8OOX5mu/iNCyUOBrqaHi7mGHx73GD01 +diNzCzvlcQqdNIH6NQSL7DTpBjca66jYT9u73vZe2MDrr1nVbuLvfu9850cdxiUO +Inv5xf8+sTHG0C+a+VAvMhsLiRjsq+lXKRJyk5zkbbsETybqpxoJ+K7CoSy3yc/k +QIY3TipwEtwkKP4hzyo6KiGd/DPexie4nBUInN3bS1BUeNZ5zeaIC2eg3bkeeW7c +qT55b+Yen6CxY0TEkzBK6AKt/WUialKMgT0wbTxRZO7kUCH3Sq6e/wXeFdJ+HvdV +LPlAg5TnMaNpRdQih/8nRFpsdwIDAQABoyAwHjAMBgNVHRMEBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAkTrKZjBrJXHps/HrjNCFPb5a +THuGPCSsepe1wkKdSp1h4HGRpLoCgcLysCJ5hZhRpHkRihhef+rFHEe60UePQO3S +CVTtdJB4CYWpcNyXOdqefrbJW5QNljxgi6Fhvs7JJkBqdXIkWXtFk2eRgOIP2Eo9 +/OHQHlYnwZFrk6sp4wPyR+A95S0toZBcyDVz7u+hOW0pGK3wviOe9lvRgj/H3Pwt +bewb0l+MhRig0/DVHamyVxrDRbqInU1/GTNCwcZkXKYFWSf92U+kIcTth24Q1gcw +eZiLl5FfrWokUNytFElXob0V0a5/kbhiLc3yWmvWqHTpqCALbVyF+rKJo2f5Kw== -----END CERTIFICATE----- diff --git a/src/php/tests/data/server1.key b/src/php/tests/data/server1.key index 143a5b87658..086462992cf 100755 --- a/src/php/tests/data/server1.key +++ b/src/php/tests/data/server1.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnE443EknxvxBq +6+hvn/t09hl8hx366EBYvZmVM/NC+7igXRAjiJiA/mIaCvL3MS0Iz5hBLxSGICU+ +WproA3GCIFITIwcf/ETyWj/5xpgZ4AKrLrjQmmX8mhwUajfF3UvwMJrCOVqPp67t +PtP+2kBXaqrXdvnvXR41FsIB8V7zIAuIZB6bHQhiGVlc1sgZYsE2EGG9WMmHtS86 +qkAOTjG2XyjmPTGAwhGDpYkYrpzp99IiDh4/Veai81hn0ssQkbry0XRD/Ig3jcHh +23WiriPNJ0JsbgXUSLKRPZObA9VgOLy2aXoN84IMaeK3yy+cwSYG/99w93fUZJte +MXwz4oYZAgMBAAECggEBAIVn2Ncai+4xbH0OLWckabwgyJ4IM9rDc0LIU368O1kU +koais8qP9dujAWgfoh3sGh/YGgKn96VnsZjKHlyMgF+r4TaDJn3k2rlAOWcurGlj +1qaVlsV4HiEzp7pxiDmHhWvp4672Bb6iBG+bsjCUOEk/n9o9KhZzIBluRhtxCmw5 +nw4Do7z00PTvN81260uPWSc04IrytvZUiAIx/5qxD72bij2xJ8t/I9GI8g4FtoVB +8pB6S/hJX1PZhh9VlU6Yk+TOfOVnbebG4W5138LkB835eqk3Zz0qsbc2euoi8Hxi +y1VGwQEmMQ63jXz4c6g+X55ifvUK9Jpn5E8pq+pMd7ECgYEA93lYq+Cr54K4ey5t +sWMa+ye5RqxjzgXj2Kqr55jb54VWG7wp2iGbg8FMlkQwzTJwebzDyCSatguEZLuB +gRGroRnsUOy9vBvhKPOch9bfKIl6qOgzMJB267fBVWx5ybnRbWN/I7RvMQf3k+9y +biCIVnxDLEEYyx7z85/5qxsXg/MCgYEA7wmWKtCTn032Hy9P8OL49T0X6Z8FlkDC +Rk42ygrc/MUbugq9RGUxcCxoImOG9JXUpEtUe31YDm2j+/nbvrjl6/bP2qWs0V7l +dTJl6dABP51pCw8+l4cWgBBX08Lkeen812AAFNrjmDCjX6rHjWHLJcpS18fnRRkP +V1d/AHWX7MMCgYEA6Gsw2guhp0Zf2GCcaNK5DlQab8OL4Hwrpttzo4kuTlwtqNKp +Q9H4al9qfF4Cr1TFya98+EVYf8yFRM3NLNjZpe3gwYf2EerlJj7VLcahw0KKzoN1 +QBENfwgPLRk5sDkx9VhSmcfl/diLroZdpAwtv3vo4nEoxeuGFbKTGx3Qkf0CgYEA +xyR+dcb05Ygm3w4klHQTowQ10s1H80iaUcZBgQuR1ghEtDbUPZHsoR5t1xCB02ys +DgAwLv1bChIvxvH/L6KM8ovZ2LekBX4AviWxoBxJnfz/EVau98B0b1auRN6eSC83 +FRuGldlSOW1z/nSh8ViizSYE5H5HX1qkXEippvFRE88CgYB3Bfu3YQY60ITWIShv +nNkdcbTT9eoP9suaRJjw92Ln+7ZpALYlQMKUZmJ/5uBmLs4RFwUTQruLOPL4yLTH +awADWUzs3IRr1fwn9E+zM8JVyKCnUEM3w4N5UZskGO2klashAd30hWO+knRv/y0r +uGIYs9Ek7YXlXIRVrzMwcsrt1w== -----END PRIVATE KEY----- diff --git a/src/php/tests/data/server1.pem b/src/php/tests/data/server1.pem index f3d43fcc5be..88244f856c6 100755 --- a/src/php/tests/data/server1.pem +++ b/src/php/tests/data/server1.pem @@ -1,16 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 +MIIDtDCCApygAwIBAgIUbJfTREJ6k6/+oInWhV1O1j3ZT0IwDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxODAzMTA0MloXDTMwMDMxNjAzMTA0MlowZTELMAkGA1UEBhMCVVMxETAPBgNV +BAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxl +LCBDby4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5xOONxJJ8b8Qauvob5/7dPYZfIcd+uhAWL2ZlTPz +Qvu4oF0QI4iYgP5iGgry9zEtCM+YQS8UhiAlPlqa6ANxgiBSEyMHH/xE8lo/+caY +GeACqy640Jpl/JocFGo3xd1L8DCawjlaj6eu7T7T/tpAV2qq13b5710eNRbCAfFe +8yALiGQemx0IYhlZXNbIGWLBNhBhvVjJh7UvOqpADk4xtl8o5j0xgMIRg6WJGK6c +6ffSIg4eP1XmovNYZ9LLEJG68tF0Q/yIN43B4dt1oq4jzSdCbG4F1EiykT2TmwPV +YDi8tml6DfOCDGnit8svnMEmBv/fcPd31GSbXjF8M+KGGQIDAQABo2swaTAJBgNV +HRMEAjAAMAsGA1UdDwQEAwIF4DBPBgNVHREESDBGghAqLnRlc3QuZ29vZ2xlLmZy +ghh3YXRlcnpvb2kudGVzdC5nb29nbGUuYmWCEioudGVzdC55b3V0dWJlLmNvbYcE +wKgBAzANBgkqhkiG9w0BAQsFAAOCAQEAS8hDQA8PSgipgAml7Q3/djwQ644ghWQv +C2Kb+r30RCY1EyKNhnQnIIh/OUbBZvh0M0iYsy6xqXgfDhCB93AA6j0i5cS8fkhH +Jl4RK0tSkGQ3YNY4NzXwQP/vmUgfkw8VBAZ4Y4GKxppdATjffIW+srbAmdDruIRM +wPeikgOoRrXf0LA1fi4TqxARzeRwenQpayNfGHTvVF9aJkl8HoaMunTAdG5pIVcr +9GKi/gEMpXUJbbVv3U5frX1Wo4CFo+rZWJ/LyCMeb0jciNLxSdMwj/E/ZuExlyeZ +gc9ctPjSMvgSyXEKv6Vwobleeg88V2ZgzenziORoWj4KszG/lbQZvg== -----END CERTIFICATE----- diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index 1d140be95f0..9e349c5b023 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -628,7 +628,7 @@ class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)): def __call__(self, context, callback): """Implements authentication by passing metadata to a callback. - Implementations of this method must not block. + This method will be invoked asynchronously in a separate thread. Args: context: An AuthMetadataContext providing information on the RPC that @@ -1076,6 +1076,14 @@ class Channel(six.with_metaclass(abc.ABCMeta)): """ raise NotImplementedError() + def __enter__(self): + """Enters the runtime context related to the channel object.""" + raise NotImplementedError() + + def __exit__(self, exc_type, exc_val, exc_tb): + """Exits the runtime context related to the channel object.""" + raise NotImplementedError() + ########################## Service-Side Context ############################## diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py index 724229a8f56..2d38320afff 100644 --- a/src/python/grpcio/grpc/_auth.py +++ b/src/python/grpcio/grpc/_auth.py @@ -14,7 +14,6 @@ """GRPCAuthMetadataPlugins for standard authentication.""" import inspect -from concurrent import futures import grpc @@ -24,43 +23,29 @@ def _sign_request(callback, token, error): callback(metadata, error) -def _create_get_token_callback(callback): - - def get_token_callback(future): - try: - access_token = future.result().access_token - except Exception as exception: # pylint: disable=broad-except - _sign_request(callback, None, exception) - else: - _sign_request(callback, access_token, None) - - return get_token_callback - - class GoogleCallCredentials(grpc.AuthMetadataPlugin): """Metadata wrapper for GoogleCredentials from the oauth2client library.""" def __init__(self, credentials): self._credentials = credentials - self._pool = futures.ThreadPoolExecutor(max_workers=1) - # Hack to determine if these are JWT creds and we need to pass # additional_claims when getting a token self._is_jwt = 'additional_claims' in inspect.getargspec( # pylint: disable=deprecated-method credentials.get_access_token).args def __call__(self, context, callback): - # MetadataPlugins cannot block (see grpc.beta.interfaces.py) - if self._is_jwt: - future = self._pool.submit( - self._credentials.get_access_token, - additional_claims={'aud': context.service_url}) + try: + if self._is_jwt: + access_token = self._credentials.get_access_token( + additional_claims={ + 'aud': context.service_url + }).access_token + else: + access_token = self._credentials.get_access_token().access_token + except Exception as exception: # pylint: disable=broad-except + _sign_request(callback, None, exception) else: - future = self._pool.submit(self._credentials.get_access_token) - future.add_done_callback(_create_get_token_callback(callback)) - - def __del__(self): - self._pool.shutdown(wait=False) + _sign_request(callback, access_token, None) class AccessTokenAuthMetadataPlugin(grpc.AuthMetadataPlugin): diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel index c7ae040a804..646d31068ca 100644 --- a/src/python/grpcio/grpc/_cython/BUILD.bazel +++ b/src/python/grpcio/grpc/_cython/BUILD.bazel @@ -2,6 +2,13 @@ package(default_visibility = ["//visibility:public"]) load("//bazel:cython_library.bzl", "pyx_library") +genrule( + name = "copy_roots_pem", + srcs = ["//:etc/roots.pem"], + outs = ["_credentials/roots.pem"], + cmd = "cp $(SRCS) $(@)", +) + pyx_library( name = "cygrpc", srcs = glob([ @@ -9,6 +16,7 @@ pyx_library( "cygrpc.pxd", "cygrpc.pyx", ]), + data = [":copy_roots_pem"], deps = [ "//:grpc", ], diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi index e70122d65e1..bfbcb8d4fc8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/call.pyx.pxi @@ -115,7 +115,7 @@ cdef class _AioCall(GrpcCallWrapper): self._channel.channel, NULL, _EMPTY_MASK, - self._channel.cq.c_ptr(), + global_completion_queue(), method_slice, NULL, c_deadline, @@ -125,7 +125,7 @@ cdef class _AioCall(GrpcCallWrapper): if credentials is not None: set_credentials_error = grpc_call_set_credentials(self.call, credentials.c()) if set_credentials_error != GRPC_CALL_OK: - raise Exception("Credentials couldn't have been set") + raise InternalError("Credentials couldn't have been set: {0}".format(set_credentials_error)) grpc_slice_unref(method_slice) @@ -178,7 +178,7 @@ cdef class _AioCall(GrpcCallWrapper): def cancel(self, str details): """Cancels the RPC in Core with given RPC status. - + Above abstractions must invoke this method to set Core objects into proper state. """ @@ -209,7 +209,7 @@ cdef class _AioCall(GrpcCallWrapper): def done(self): """Returns if the RPC call has finished. - + Checks if the status has been provided, either because the RPC finished or because was cancelled.. @@ -220,7 +220,7 @@ cdef class _AioCall(GrpcCallWrapper): def cancelled(self): """Returns if the RPC was cancelled. - + Returns: True if the RPC was cancelled. """ @@ -231,7 +231,7 @@ cdef class _AioCall(GrpcCallWrapper): async def status(self): """Returns the status of the RPC call. - + It returns the finshed status of the RPC. If the RPC has not finished yet this function will wait until the RPC gets finished. @@ -254,7 +254,7 @@ cdef class _AioCall(GrpcCallWrapper): async def initial_metadata(self): """Returns the initial metadata of the RPC call. - + If the initial metadata has not been received yet this function will wait until the RPC gets finished. @@ -286,7 +286,7 @@ cdef class _AioCall(GrpcCallWrapper): bytes request, tuple outbound_initial_metadata): """Performs a unary unary RPC. - + Args: request: the serialized requests in bytes. outbound_initial_metadata: optional outbound metadata. @@ -420,7 +420,7 @@ cdef class _AioCall(GrpcCallWrapper): tuple outbound_initial_metadata, object metadata_sent_observer): """Actual implementation of the complete unary-stream call. - + Needs to pay extra attention to the raise mechanism. If we want to propagate the final status exception, then we have to raise it. Othersize, it would end normally and raise `StopAsyncIteration()`. @@ -490,7 +490,7 @@ cdef class _AioCall(GrpcCallWrapper): outbound_initial_metadata, self._send_initial_metadata_flags, self._loop) - # Notify upper level that sending messages are allowed now. + # Notify upper level that sending messages are allowed now. metadata_sent_observer() # Receives initial metadata. diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pxd.pxi index 70a1c9b3f27..e5620cd166d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pxd.pxi @@ -35,6 +35,7 @@ cdef struct CallbackContext: # management. grpc_experimental_completion_queue_functor functor cpython.PyObject *waiter + cpython.PyObject *loop cpython.PyObject *failure_handler cpython.PyObject *callback_wrapper diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pyx.pxi index 33713b8ad64..86fc91e76a4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/callback_common.pyx.pxi @@ -32,9 +32,10 @@ cdef class CallbackFailureHandler: cdef class CallbackWrapper: - def __cinit__(self, object future, CallbackFailureHandler failure_handler): + def __cinit__(self, object future, object loop, CallbackFailureHandler failure_handler): self.context.functor.functor_run = self.functor_run self.context.waiter = future + self.context.loop = loop self.context.failure_handler = failure_handler self.context.callback_wrapper = self # NOTE(lidiz) Not using a list here, because this class is critical in @@ -69,7 +70,8 @@ cdef CallbackFailureHandler CQ_SHUTDOWN_FAILURE_HANDLER = CallbackFailureHandler InternalError) -class ExecuteBatchError(Exception): pass +class ExecuteBatchError(InternalError): + """Raised when execute batch returns a failure from Core.""" async def execute_batch(GrpcCallWrapper grpc_call_wrapper, @@ -82,6 +84,7 @@ async def execute_batch(GrpcCallWrapper grpc_call_wrapper, cdef object future = loop.create_future() cdef CallbackWrapper wrapper = CallbackWrapper( future, + loop, CallbackFailureHandler('execute_batch', operations, ExecuteBatchError)) cdef grpc_call_error error = grpc_call_start_batch( grpc_call_wrapper.call, @@ -126,7 +129,7 @@ async def _receive_message(GrpcCallWrapper grpc_call_wrapper, # the callback (e.g. cancelled). # # Since they all indicates finish, they are better be merged. - _LOGGER.debug(e) + _LOGGER.debug('Failed to receive any message from Core') return receive_op.message() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pxd.pxi index 569e6763c54..03b4990e488 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pxd.pxi @@ -21,7 +21,7 @@ cdef enum AioChannelStatus: cdef class AioChannel: cdef: grpc_channel * channel - BaseCompletionQueue cq object loop bytes _target AioChannelStatus _status + bint _is_secure diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi index fa99371b211..beadce67b4a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/channel.pyx.pxi @@ -27,26 +27,31 @@ cdef CallbackFailureHandler _WATCH_CONNECTIVITY_FAILURE_HANDLER = CallbackFailur cdef class AioChannel: def __cinit__(self, bytes target, tuple options, ChannelCredentials credentials, object loop): + init_grpc_aio() if options is None: options = () cdef _ChannelArgs channel_args = _ChannelArgs(options) self._target = target - self.cq = create_completion_queue() self.loop = loop self._status = AIO_CHANNEL_STATUS_READY if credentials is None: + self._is_secure = False self.channel = grpc_insecure_channel_create( target, channel_args.c_args(), NULL) else: + self._is_secure = True self.channel = grpc_secure_channel_create( credentials.c(), target, channel_args.c_args(), NULL) + def __dealloc__(self): + shutdown_grpc_aio() + def __repr__(self): class_name = self.__class__.__name__ id_ = id(self) @@ -78,12 +83,13 @@ cdef class AioChannel: cdef object future = self.loop.create_future() cdef CallbackWrapper wrapper = CallbackWrapper( future, + self.loop, _WATCH_CONNECTIVITY_FAILURE_HANDLER) grpc_channel_watch_connectivity_state( self.channel, last_observed_state, c_deadline, - self.cq.c_ptr(), + global_completion_queue(), wrapper.c_functor()) try: @@ -111,13 +117,16 @@ cdef class AioChannel: """Assembles a Cython Call object. Returns: - The _AioCall object. + An _AioCall object. """ if self.closed(): raise UsageError('Channel is closed.') cdef CallCredentials cython_call_credentials if python_call_credentials is not None: + if not self._is_secure: + raise UsageError("Call credentials are only valid on secure channels") + cython_call_credentials = python_call_credentials._credentials else: cython_call_credentials = None diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi index 27d16cb0475..6af2499e6e8 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/common.pyx.pxi @@ -99,3 +99,16 @@ class AbortError(BaseError): class InternalError(BaseError): """Raised upon unexpected errors in native code.""" + + +def schedule_coro_threadsafe(object coro, object loop): + try: + return loop.create_task(coro) + except RuntimeError as runtime_error: + if 'Non-thread-safe operation' in str(runtime_error): + return asyncio.run_coroutine_threadsafe( + coro, + loop, + ) + else: + raise diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pxd.pxi index 54a0e90184a..e69200c7376 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pxd.pxi @@ -12,6 +12,38 @@ # See the License for the specific language governing permissions and # limitations under the License. +# NOTE(lidiz) Unfortunately, we can't use "cimport" here because Cython +# links it with exception handling. It introduces new dependencies. +cdef extern from "" namespace "std" nogil: + cdef cppclass queue[T]: + queue() + bint empty() + T& front() + void pop() + void push(T&) + size_t size() + + +cdef extern from "" namespace "std" nogil: + cdef cppclass mutex: + mutex() + void lock() + void unlock() + + +ctypedef queue[grpc_event] cpp_event_queue + + +IF UNAME_SYSNAME == "Windows": + cdef extern from "winsock2.h" nogil: + ctypedef uint32_t WIN_SOCKET "SOCKET" + WIN_SOCKET win_socket "socket" (int af, int type, int protocol) + int win_socket_send "send" (WIN_SOCKET s, const char *buf, int len, int flags) + + +cdef void _unified_socket_write(int fd) nogil + + cdef class BaseCompletionQueue: cdef grpc_completion_queue *_cq @@ -19,12 +51,19 @@ cdef class BaseCompletionQueue: cdef class PollerCompletionQueue(BaseCompletionQueue): cdef bint _shutdown - cdef object _shutdown_completed + cdef cpp_event_queue _queue + cdef mutex _queue_mutex cdef object _poller_thread + cdef int _write_fd + cdef object _read_socket + cdef object _write_socket + cdef object _loop - cdef void _poll(self) except * + cdef void _poll(self) nogil + cdef shutdown(self) cdef class CallbackCompletionQueue(BaseCompletionQueue): cdef object _shutdown_completed # asyncio.Future cdef CallbackWrapper _wrapper + cdef object _loop diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi index 7dd1f68f10c..15d2e18f3d7 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/completion_queue.pyx.pxi @@ -12,18 +12,27 @@ # See the License for the specific language governing permissions and # limitations under the License. +import socket + cdef gpr_timespec _GPR_INF_FUTURE = gpr_inf_future(GPR_CLOCK_REALTIME) +IF UNAME_SYSNAME == "Windows": + cdef void _unified_socket_write(int fd) nogil: + win_socket_send(fd, b"1", 1, 0) +ELSE: + from posix cimport unistd + + cdef void _unified_socket_write(int fd) nogil: + unistd.write(fd, b"1", 1) + + def _handle_callback_wrapper(CallbackWrapper callback_wrapper, int success): CallbackWrapper.functor_run(callback_wrapper.c_functor(), success) cdef class BaseCompletionQueue: - async def shutdown(self): - raise NotImplementedError() - cdef grpc_completion_queue* c_ptr(self): return self._cq @@ -31,50 +40,87 @@ cdef class BaseCompletionQueue: cdef class PollerCompletionQueue(BaseCompletionQueue): def __cinit__(self): + self._loop = asyncio.get_event_loop() self._cq = grpc_completion_queue_create_for_next(NULL) self._shutdown = False - self._shutdown_completed = asyncio.get_event_loop().create_future() self._poller_thread = threading.Thread(target=self._poll_wrapper, daemon=True) self._poller_thread.start() - cdef void _poll(self) except *: + self._read_socket, self._write_socket = socket.socketpair() + self._write_fd = self._write_socket.fileno() + self._loop.add_reader(self._read_socket, self._handle_events) + + self._queue = cpp_event_queue() + + cdef void _poll(self) nogil: cdef grpc_event event cdef CallbackContext *context while not self._shutdown: - with nogil: - event = grpc_completion_queue_next(self._cq, + event = grpc_completion_queue_next(self._cq, _GPR_INF_FUTURE, NULL) if event.type == GRPC_QUEUE_TIMEOUT: - raise AssertionError("Core should not return timeout error!") + with gil: + raise AssertionError("Core should not return GRPC_QUEUE_TIMEOUT!") elif event.type == GRPC_QUEUE_SHUTDOWN: self._shutdown = True - aio_loop_call_soon_threadsafe(self._shutdown_completed.set_result, None) else: - context = event.tag - aio_loop_call_soon_threadsafe( - _handle_callback_wrapper, - context.callback_wrapper, - event.success) + self._queue_mutex.lock() + self._queue.push(event) + self._queue_mutex.unlock() + _unified_socket_write(self._write_fd) def _poll_wrapper(self): - self._poll() + with nogil: + self._poll() - async def shutdown(self): + cdef shutdown(self): + self._loop.remove_reader(self._read_socket) + # TODO(https://github.com/grpc/grpc/issues/22365) perform graceful shutdown grpc_completion_queue_shutdown(self._cq) - await self._shutdown_completed grpc_completion_queue_destroy(self._cq) - self._poller_thread.join() + + def _handle_events(self): + cdef bytes data = self._read_socket.recv(1) + cdef grpc_event event + cdef CallbackContext *context + + while True: + self._queue_mutex.lock() + if self._queue.empty(): + self._queue_mutex.unlock() + break + else: + event = self._queue.front() + self._queue.pop() + self._queue_mutex.unlock() + + context = event.tag + loop = context.loop + if loop is self._loop: + # Executes callbacks: complete the future + CallbackWrapper.functor_run( + event.tag, + event.success + ) + else: + loop.call_soon_threadsafe( + _handle_callback_wrapper, + context.callback_wrapper, + event.success + ) cdef class CallbackCompletionQueue(BaseCompletionQueue): def __cinit__(self): - self._shutdown_completed = grpc_aio_loop().create_future() + self._loop = asyncio.get_event_loop() + self._shutdown_completed = self._loop.create_future() self._wrapper = CallbackWrapper( self._shutdown_completed, + self._loop, CQ_SHUTDOWN_FAILURE_HANDLER) self._cq = grpc_completion_queue_create_for_callback( self._wrapper.c_functor(), @@ -85,12 +131,3 @@ cdef class CallbackCompletionQueue(BaseCompletionQueue): grpc_completion_queue_shutdown(self._cq) await self._shutdown_completed grpc_completion_queue_destroy(self._cq) - - -cdef BaseCompletionQueue create_completion_queue(): - if grpc_aio_engine is AsyncIOEngine.CUSTOM_IO_MANAGER: - return CallbackCompletionQueue() - elif grpc_aio_engine is AsyncIOEngine.POLLER: - return PollerCompletionQueue() - else: - raise ValueError('Unsupported engine type [%s]' % grpc_aio_engine) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pxd.pxi index 9b9252ff3a5..ebf0660174d 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pxd.pxi @@ -13,14 +13,31 @@ # limitations under the License. # distutils: language=c++ +cdef class _AioState: + cdef object lock # threading.RLock + cdef int refcount + cdef object engine # AsyncIOEngine + cdef BaseCompletionQueue cq + + +cdef grpc_completion_queue *global_completion_queue() + + +cpdef init_grpc_aio() + + +cpdef shutdown_grpc_aio() + cdef extern from "src/core/lib/iomgr/timer_manager.h": - void grpc_timer_manager_set_threading(bint enabled); + void grpc_timer_manager_set_threading(bint enabled) + cdef extern from "src/core/lib/iomgr/iomgr_internal.h": - void grpc_set_default_iomgr_platform(); + void grpc_set_default_iomgr_platform() + cdef extern from "src/core/lib/iomgr/executor.h" namespace "grpc_core": cdef cppclass Executor: @staticmethod - void SetThreadingAll(bint enable); + void SetThreadingAll(bint enable) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi index 9a6fdecace3..4231ca7d8ab 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/grpc_aio.pyx.pxi @@ -12,98 +12,125 @@ # See the License for the specific language governing permissions and # limitations under the License. +import enum -cdef bint _grpc_aio_initialized = False -# NOTE(lidiz) Theoretically, applications can run in multiple event loops as -# long as they are in the same thread with same magic. This is not a supported -# use case. So, the gRPC Python Async Stack should use a single event loop -# picked by "init_grpc_aio". -cdef object _grpc_aio_loop # asyncio.AbstractEventLoop -cdef int64_t _event_loop_thread_ident -cdef str _GRPC_ASYNCIO_ENGINE = os.environ.get('GRPC_ASYNCIO_ENGINE', 'default').lower() -grpc_aio_engine = None -cdef object _grpc_initialization_lock = threading.Lock() +cdef str _GRPC_ASYNCIO_ENGINE = os.environ.get('GRPC_ASYNCIO_ENGINE', 'poller').upper() +cdef _AioState _global_aio_state = _AioState() class AsyncIOEngine(enum.Enum): - DEFAULT = 'default' - CUSTOM_IO_MANAGER = 'custom' + CUSTOM_IO_MANAGER = 'custom_io_manager' POLLER = 'poller' -def init_grpc_aio(): - global _grpc_aio_initialized - global _grpc_aio_loop - global _event_loop_thread_ident - global grpc_aio_engine - - with _grpc_initialization_lock: - # Marks this function as called - if _grpc_aio_initialized: - return - else: - _grpc_aio_initialized = True - - # Picks the engine for gRPC AsyncIO Stack - for engine_type in AsyncIOEngine: - if engine_type.value == _GRPC_ASYNCIO_ENGINE: - grpc_aio_engine = engine_type - break - if grpc_aio_engine is None or grpc_aio_engine is AsyncIOEngine.DEFAULT: - grpc_aio_engine = AsyncIOEngine.CUSTOM_IO_MANAGER - - # Anchors the event loop that the gRPC library going to use. - _grpc_aio_loop = asyncio.get_event_loop() - _event_loop_thread_ident = threading.current_thread().ident - - if grpc_aio_engine is AsyncIOEngine.CUSTOM_IO_MANAGER: - # Activates asyncio IO manager. - # NOTE(lidiz) Custom IO manager must be activated before the first - # `grpc_init()`. Otherwise, some special configurations in Core won't - # pick up the change, and resulted in SEGFAULT or ABORT. - install_asyncio_iomgr() - - # TODO(https://github.com/grpc/grpc/issues/22244) we need a the - # grpc_shutdown_blocking() counterpart for this call. Otherwise, the gRPC - # library won't shutdown cleanly. - grpc_init() - - # Timers are triggered by the Asyncio loop. We disable - # the background thread that is being used by the native - # gRPC iomgr. - grpc_timer_manager_set_threading(False) - - # gRPC callbaks are executed within the same thread used by the Asyncio - # event loop, as it is being done by the other Asyncio callbacks. - Executor.SetThreadingAll(False) - else: - # TODO(https://github.com/grpc/grpc/issues/22244) we need a the - # grpc_shutdown_blocking() counterpart for this call. Otherwise, the gRPC - # library won't shutdown cleanly. - grpc_init() - - -def grpc_aio_loop(): - """Returns the one-and-only gRPC Aio event loop.""" - return _grpc_aio_loop - - -def aio_loop_schedule_coroutine(object coro): - """Thread-safely schedules coroutine to gRPC Aio event loop. - - If invoked within the same thread as the event loop, return an - Asyncio.Task. Otherwise, return a concurrent.futures.Future (the sync - Future). For non-asyncio threads, sync Future objects are probably easier - to handle (without worrying other thread-safety stuff). +cdef _default_asyncio_engine(): + return AsyncIOEngine.POLLER + + +cdef grpc_completion_queue *global_completion_queue(): + return _global_aio_state.cq.c_ptr() + + +cdef class _AioState: + + def __cinit__(self): + self.lock = threading.RLock() + self.refcount = 0 + self.engine = None + self.cq = None + + +cdef _initialize_custom_io_manager(): + # Activates asyncio IO manager. + # NOTE(lidiz) Custom IO manager must be activated before the first + # `grpc_init()`. Otherwise, some special configurations in Core won't + # pick up the change, and resulted in SEGFAULT or ABORT. + install_asyncio_iomgr() + + # Initializes gRPC Core, must be called before other Core API + grpc_init() + + # Timers are triggered by the Asyncio loop. We disable + # the background thread that is being used by the native + # gRPC iomgr. + grpc_timer_manager_set_threading(False) + + # gRPC callbaks are executed within the same thread used by the Asyncio + # event loop, as it is being done by the other Asyncio callbacks. + Executor.SetThreadingAll(False) + + # Creates the only completion queue + _global_aio_state.cq = CallbackCompletionQueue() + + +cdef _initialize_poller(): + # Initializes gRPC Core, must be called before other Core API + grpc_init() + + # Creates the only completion queue + _global_aio_state.cq = PollerCompletionQueue() + + +cdef _actual_aio_initialization(): + # Picks the engine for gRPC AsyncIO Stack + _global_aio_state.engine = AsyncIOEngine.__members__.get( + _GRPC_ASYNCIO_ENGINE, + _default_asyncio_engine(), + ) + _LOGGER.debug('Using %s as I/O engine', _global_aio_state.engine) + + # Initializes the process-level state accordingly + if _global_aio_state.engine is AsyncIOEngine.CUSTOM_IO_MANAGER: + _initialize_custom_io_manager() + elif _global_aio_state.engine is AsyncIOEngine.POLLER: + _initialize_poller() + else: + raise ValueError('Unsupported engine type [%s]' % _global_aio_state.engine) + + +def _grpc_shutdown_wrapper(_): + """A thin Python wrapper of Core's shutdown function. + + Define functions are not allowed in "cdef" functions, and Cython complains + about a simple lambda with a C function. """ - if _event_loop_thread_ident != threading.current_thread().ident: - return asyncio.run_coroutine_threadsafe(coro, _grpc_aio_loop) + grpc_shutdown_blocking() + + +cdef _actual_aio_shutdown(): + if _global_aio_state.engine is AsyncIOEngine.CUSTOM_IO_MANAGER: + future = schedule_coro_threadsafe( + _global_aio_state.cq.shutdown(), + (_global_aio_state.cq)._loop + ) + future.add_done_callback(_grpc_shutdown_wrapper) + elif _global_aio_state.engine is AsyncIOEngine.POLLER: + _global_aio_state.cq.shutdown() + grpc_shutdown_blocking() else: - return _grpc_aio_loop.create_task(coro) + raise ValueError('Unsupported engine type [%s]' % _global_aio_state.engine) -def aio_loop_call_soon_threadsafe(object func, *args): - # TODO(lidiz) After we are confident, we can drop this assert. Otherwsie, - # we should limit this function to non-grpc-event-loop thread. - assert _event_loop_thread_ident != threading.current_thread().ident - return _grpc_aio_loop.call_soon_threadsafe(func, *args) +cpdef init_grpc_aio(): + """Initializes the gRPC AsyncIO module. + + Expected to be invoked on critical class constructors. + E.g., AioChannel, AioServer. + """ + with _global_aio_state.lock: + _global_aio_state.refcount += 1 + if _global_aio_state.refcount == 1: + _actual_aio_initialization() + + +cpdef shutdown_grpc_aio(): + """Shuts down the gRPC AsyncIO module. + + Expected to be invoked on critical class destructors. + E.g., AioChannel, AioServer. + """ + with _global_aio_state.lock: + assert _global_aio_state.refcount > 0 + _global_aio_state.refcount -= 1 + if not _global_aio_state.refcount: + _actual_aio_shutdown() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/iomgr.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/iomgr.pyx.pxi index ac62c41e0f2..f5b62af5287 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/iomgr.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/iomgr.pyx.pxi @@ -212,7 +212,18 @@ cdef void asyncio_run_loop(size_t timeout_ms) with gil: pass +def _auth_plugin_callback_wrapper(object cb, + str service_url, + str method_name, + object callback): + asyncio.get_event_loop().call_soon(cb, service_url, method_name, callback) + + def install_asyncio_iomgr(): + # Auth plugins invoke user provided logic in another thread by default. We + # need to override that behavior by registering the call to the event loop. + set_async_callback_func(_auth_plugin_callback_wrapper) + asyncio_resolver_vtable.resolve = asyncio_resolve asyncio_resolver_vtable.resolve_async = asyncio_resolve_async diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pxd.pxi index 26089c95337..35d4e484b09 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pxd.pxi @@ -14,6 +14,7 @@ cdef class _AsyncioResolver: cdef: + object _loop grpc_custom_resolver* _grpc_resolver object _task_resolve diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pyx.pxi index 7d47fa77b00..4983eab5113 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/resolver.pyx.pxi @@ -15,6 +15,7 @@ cdef class _AsyncioResolver: def __cinit__(self): + self._loop = asyncio.get_event_loop() self._grpc_resolver = NULL self._task_resolve = None @@ -32,7 +33,7 @@ cdef class _AsyncioResolver: async def _async_resolve(self, bytes host, bytes port): self._task_resolve = None try: - resolved = await grpc_aio_loop().getaddrinfo(host, port) + resolved = await self._loop.getaddrinfo(host, port) except Exception as e: grpc_custom_resolve_callback( self._grpc_resolver, @@ -50,6 +51,6 @@ cdef class _AsyncioResolver: cdef void resolve(self, char* host, char* port): assert not self._task_resolve - self._task_resolve = grpc_aio_loop().create_task( + self._task_resolve = self._loop.create_task( self._async_resolve(host, port) ) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/socket.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/socket.pyx.pxi index f46e657c263..7524e9da94b 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/socket.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/socket.pyx.pxi @@ -37,6 +37,7 @@ cdef class _AsyncioSocket: self._py_socket = None self._peername = None self._closed = False + self._loop = asyncio.get_event_loop() @staticmethod cdef _AsyncioSocket create(grpc_custom_socket * grpc_socket, @@ -90,7 +91,7 @@ cdef class _AsyncioSocket: assert not self._reader assert not self._task_connect - self._task_connect = grpc_aio_loop().create_task( + self._task_connect = self._loop.create_task( self._async_connect(host, port) ) self._grpc_connect_cb = grpc_connect_cb @@ -122,7 +123,7 @@ cdef class _AsyncioSocket: self._grpc_read_cb = grpc_read_cb self._read_buffer = buffer_ - self._task_read = grpc_aio_loop().create_task(self._async_read(length)) + self._task_read = self._loop.create_task(self._async_read(length)) async def _async_write(self, bytearray outbound_buffer): self._writer.write(outbound_buffer) @@ -155,7 +156,7 @@ cdef class _AsyncioSocket: outbound_buffer.extend(start[:length]) self._grpc_write_cb = grpc_write_cb - self._task_write = grpc_aio_loop().create_task(self._async_write(outbound_buffer)) + self._task_write = self._loop.create_task(self._async_write(outbound_buffer)) cdef bint is_connected(self): return self._reader and not self._reader._transport.is_closing() @@ -209,7 +210,7 @@ cdef class _AsyncioSocket: sock=self._py_socket, ) - self._task_listen = grpc_aio_loop().create_task(create_asyncio_server()) + self._task_listen = self._loop.create_task(create_asyncio_server()) cdef accept(self, grpc_custom_socket* grpc_socket_client, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pxd.pxi index d2979c86b49..76c3be0c57c 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pxd.pxi @@ -17,6 +17,7 @@ cdef class _AsyncioTimer: grpc_custom_timer * _grpc_timer object _timer_future bint _active + object _loop @staticmethod cdef _AsyncioTimer create(grpc_custom_timer * grpc_timer, float timeout) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pyx.pxi index 51145116e21..286cd9a9d43 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/iomgr/timer.pyx.pxi @@ -18,13 +18,14 @@ cdef class _AsyncioTimer: self._grpc_timer = NULL self._timer_future = None self._active = False + self._loop = asyncio.get_event_loop() cpython.Py_INCREF(self) @staticmethod cdef _AsyncioTimer create(grpc_custom_timer * grpc_timer, float timeout): timer = _AsyncioTimer() timer._grpc_timer = grpc_timer - timer._timer_future = grpc_aio_loop().call_later(timeout, timer.on_time_up) + timer._timer_future = timer._loop.call_later(timeout, timer.on_time_up) timer._active = True return timer diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pxd.pxi index 18fc9214b27..52f491614f1 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pxd.pxi @@ -41,6 +41,18 @@ cdef class RPCState(GrpcCallWrapper): cdef Operation create_send_initial_metadata_op_if_not_sent(self) +cdef class _ServicerContext: + cdef RPCState _rpc_state + cdef object _loop # asyncio.AbstractEventLoop + cdef object _request_deserializer # Callable[[bytes], Any] + cdef object _response_serializer # Callable[[Any], bytes] + + +cdef class _MessageReceiver: + cdef _ServicerContext _servicer_context + cdef object _agen + + cdef enum AioServerStatus: AIO_SERVER_STATUS_UNKNOWN AIO_SERVER_STATUS_READY @@ -51,7 +63,6 @@ cdef enum AioServerStatus: cdef class AioServer: cdef Server _server - cdef BaseCompletionQueue _cq cdef list _generic_handlers cdef AioServerStatus _status cdef object _loop # asyncio.EventLoop diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi index d8ed9a41fe7..b0c62f9b9f2 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/aio/server.pyx.pxi @@ -109,10 +109,6 @@ cdef class RPCState: cdef class _ServicerContext: - cdef RPCState _rpc_state - cdef object _loop - cdef object _request_deserializer - cdef object _response_serializer def __cinit__(self, RPCState rpc_state, @@ -128,9 +124,9 @@ cdef class _ServicerContext: cdef bytes raw_message self._rpc_state.raise_for_termination() - if self._rpc_state.client_closed: - return EOF raw_message = await _receive_message(self._rpc_state, self._loop) + self._rpc_state.raise_for_termination() + if raw_message is None: return EOF else: @@ -414,15 +410,28 @@ async def _handle_unary_stream_rpc(object method_handler, ) -async def _message_receiver(_ServicerContext servicer_context): +cdef class _MessageReceiver: """Bridge between the async generator API and the reader-writer API.""" - cdef object message - while True: - message = await servicer_context.read() - if message is not EOF: - yield message - else: - break + + def __cinit__(self, _ServicerContext servicer_context): + self._servicer_context = servicer_context + self._agen = None + + async def _async_message_receiver(self): + """An async generator that receives messages.""" + cdef object message + while True: + message = await self._servicer_context.read() + if message is not EOF: + yield message + else: + break + + def __aiter__(self): + # Prevents never awaited warning if application never used the async generator + if self._agen is None: + self._agen = self._async_message_receiver() + return self._agen async def _handle_stream_unary_rpc(object method_handler, @@ -437,7 +446,7 @@ async def _handle_stream_unary_rpc(object method_handler, ) # Prepares the request generator - cdef object request_async_iterator = _message_receiver(servicer_context) + cdef object request_async_iterator = _MessageReceiver(servicer_context) # Finishes the application handler await _finish_handler_with_unary_response( @@ -462,7 +471,7 @@ async def _handle_stream_stream_rpc(object method_handler, ) # Prepares the request generator - cdef object request_async_iterator = _message_receiver(servicer_context) + cdef object request_async_iterator = _MessageReceiver(servicer_context) # Finishes the application handler await _finish_handler_with_stream_responses( @@ -494,7 +503,13 @@ async def _handle_exceptions(RPCState rpc_state, object rpc_coro, object loop): except asyncio.CancelledError: _LOGGER.debug('RPC cancelled for servicer method [%s]', _decode(rpc_state.method())) except _ServerStoppedError: - _LOGGER.info('Aborting RPC due to server stop.') + _LOGGER.warning('Aborting method [%s] due to server stop.', _decode(rpc_state.method())) + except ExecuteBatchError: + # If client closed (aka. cancelled), ignore the failed batch operations. + if rpc_state.client_closed: + return + else: + raise except Exception as e: _LOGGER.exception('Unexpected [%s] raised by servicer method [%s]' % ( type(e).__name__, @@ -610,13 +625,13 @@ cdef class AioServer: def __init__(self, loop, thread_pool, generic_handlers, interceptors, options, maximum_concurrent_rpcs): + init_grpc_aio() # NOTE(lidiz) Core objects won't be deallocated automatically. # If AioServer.shutdown is not called, those objects will leak. self._server = Server(options) - self._cq = create_completion_queue() grpc_server_register_completion_queue( self._server.c_server, - self._cq.c_ptr(), + global_completion_queue(), NULL ) @@ -631,6 +646,7 @@ cdef class AioServer: self._shutdown_completed = self._loop.create_future() self._shutdown_callback_wrapper = CallbackWrapper( self._shutdown_completed, + self._loop, SERVER_SHUTDOWN_FAILURE_HANDLER) self._crash_exception = None @@ -659,11 +675,12 @@ cdef class AioServer: cdef object future = self._loop.create_future() cdef CallbackWrapper wrapper = CallbackWrapper( future, + self._loop, REQUEST_CALL_FAILURE_HANDLER) error = grpc_server_request_call( self._server.c_server, &rpc_state.call, &rpc_state.details, &rpc_state.request_metadata, - self._cq.c_ptr(), self._cq.c_ptr(), + global_completion_queue(), global_completion_queue(), wrapper.c_functor() ) if error != GRPC_CALL_OK: @@ -674,7 +691,7 @@ cdef class AioServer: async def _server_main_loop(self, object server_started): - self._server.start() + self._server.start(backup_queue=False) cdef RPCState rpc_state server_started.set_result(True) @@ -736,7 +753,7 @@ cdef class AioServer: # The shutdown callback won't be called until there is no live RPC. grpc_server_shutdown_and_notify( self._server.c_server, - self._cq.c_ptr(), + global_completion_queue(), self._shutdown_callback_wrapper.c_functor()) # Ensures the serving task (coroutine) exits. @@ -789,9 +806,6 @@ cdef class AioServer: self._server.is_shutdown = True self._status = AIO_SERVER_STATUS_STOPPED - # Shuts down the completion queue - await self._cq.shutdown() - async def wait_for_termination(self, object timeout): if timeout is None: await self._shutdown_completed @@ -823,3 +837,4 @@ cdef class AioServer: self, self._status ) + shutdown_grpc_aio() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index c736b7a10c5..24d1e2a3b77 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -34,12 +34,14 @@ cdef class CallCredentials: raise NotImplementedError() -cdef int _get_metadata( - void *state, grpc_auth_metadata_context context, - grpc_credentials_plugin_metadata_cb cb, void *user_data, - grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], - size_t *num_creds_md, grpc_status_code *status, - const char **error_details) except * with gil: +cdef int _get_metadata(void *state, + grpc_auth_metadata_context context, + grpc_credentials_plugin_metadata_cb cb, + void *user_data, + grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX], + size_t *num_creds_md, + grpc_status_code *status, + const char **error_details) except * with gil: cdef size_t metadata_count cdef grpc_metadata *c_metadata def callback(metadata, grpc_status_code status, bytes error_details): diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index 5910f10abfd..b0a753c7ebe 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -20,7 +20,6 @@ import os import sys import threading import time -import enum import grpc diff --git a/src/python/grpcio/grpc/experimental/aio/__init__.py b/src/python/grpcio/grpc/experimental/aio/__init__.py index 899fea38a49..634795e7cc3 100644 --- a/src/python/grpcio/grpc/experimental/aio/__init__.py +++ b/src/python/grpcio/grpc/experimental/aio/__init__.py @@ -20,8 +20,9 @@ created. AsyncIO doesn't provide thread safety for most of its APIs. from typing import Any, Optional, Sequence, Tuple import grpc -from grpc._cython.cygrpc import (EOF, AbortError, BaseError, InternalError, - UsageError, init_grpc_aio) +from grpc._cython.cygrpc import (init_grpc_aio, shutdown_grpc_aio, EOF, + AbortError, BaseError, InternalError, + UsageError) from ._base_call import (Call, RpcContext, StreamStreamCall, StreamUnaryCall, UnaryStreamCall, UnaryUnaryCall) @@ -35,10 +36,13 @@ from ._server import server from ._base_server import Server, ServicerContext from ._typing import ChannelArgumentType from ._channel import insecure_channel, secure_channel +from ._metadata import Metadata ################################### __all__ ################################# __all__ = ( + 'init_grpc_aio', + 'shutdown_grpc_aio', 'AioRpcError', 'RpcContext', 'Call', @@ -46,7 +50,6 @@ __all__ = ( 'UnaryStreamCall', 'StreamUnaryCall', 'StreamStreamCall', - 'init_grpc_aio', 'Channel', 'UnaryUnaryMultiCallable', 'UnaryStreamMultiCallable', @@ -66,4 +69,5 @@ __all__ = ( 'BaseError', 'UsageError', 'InternalError', + 'Metadata', ) diff --git a/src/python/grpcio/grpc/experimental/aio/_channel.py b/src/python/grpcio/grpc/experimental/aio/_channel.py index 300a1b3490d..24a38e1f3d0 100644 --- a/src/python/grpcio/grpc/experimental/aio/_channel.py +++ b/src/python/grpcio/grpc/experimental/aio/_channel.py @@ -228,7 +228,7 @@ class Channel(_base_channel.Channel): "UnaryUnaryClientInterceptors, the following are invalid: {}"\ .format(invalid_interceptors)) - self._loop = cygrpc.grpc_aio_loop() + self._loop = asyncio.get_event_loop() self._channel = cygrpc.AioChannel( _common.encode(target), _augment_channel_arguments(options, compression), credentials, diff --git a/src/python/grpcio/grpc/experimental/aio/_metadata.py b/src/python/grpcio/grpc/experimental/aio/_metadata.py new file mode 100644 index 00000000000..ff970106748 --- /dev/null +++ b/src/python/grpcio/grpc/experimental/aio/_metadata.py @@ -0,0 +1,105 @@ +# Copyright 2020 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. +"""Implementation of the metadata abstraction for gRPC Asyncio Python.""" +from typing import List, Tuple, Iterator, Any, Text, Union +from collections import abc, OrderedDict + +MetadataKey = Text +MetadataValue = Union[str, bytes] + + +class Metadata(abc.Mapping): + """Metadata abstraction for the asynchronous calls and interceptors. + + The metadata is a mapping from str -> List[str] + + Traits + * Multiple entries are allowed for the same key + * The order of the values by key is preserved + * Getting by an element by key, retrieves the first mapped value + * Supports an immutable view of the data + * Allows partial mutation on the data without recreating the new object from scratch. + """ + + def __init__(self, *args: Tuple[MetadataKey, MetadataValue]) -> None: + self._metadata = OrderedDict() + for md_key, md_value in args: + self.add(md_key, md_value) + + def add(self, key: MetadataKey, value: MetadataValue) -> None: + self._metadata.setdefault(key, []) + self._metadata[key].append(value) + + def __len__(self) -> int: + """Return the total number of elements that there are in the metadata, + including multiple values for the same key. + """ + return sum(map(len, self._metadata.values())) + + def __getitem__(self, key: MetadataKey) -> MetadataValue: + """When calling [], the first element of all those + mapped for is returned. + """ + try: + return self._metadata[key][0] + except (ValueError, IndexError) as e: + raise KeyError("{0!r}".format(key)) from e + + def __setitem__(self, key: MetadataKey, value: MetadataValue) -> None: + """Calling metadata[] = + Maps to the first instance of . + """ + if key not in self: + self._metadata[key] = [value] + else: + current_values = self.get_all(key) + self._metadata[key] = [value, *current_values[1:]] + + def __delitem__(self, key: MetadataKey) -> None: + """``del metadata[]`` deletes the first mapping for .""" + current_values = self.get_all(key) + if not current_values: + raise KeyError(repr(key)) + self._metadata[key] = current_values[1:] + + def delete_all(self, key: MetadataKey) -> None: + """Delete all mappings for .""" + del self._metadata[key] + + def __iter__(self) -> Iterator[Tuple[MetadataKey, MetadataValue]]: + for key, values in self._metadata.items(): + for value in values: + yield (key, value) + + def get_all(self, key: MetadataKey) -> List[MetadataValue]: + """For compatibility with other Metadata abstraction objects (like in Java), + this would return all items under the desired . + """ + return self._metadata.get(key, []) + + def set_all(self, key: MetadataKey, values: List[MetadataValue]) -> None: + self._metadata[key] = values + + def __contains__(self, key: MetadataKey) -> bool: + return key in self._metadata + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, self.__class__): + return NotImplemented # pytype: disable=bad-return-type + + return self._metadata == other._metadata + + def __repr__(self) -> str: + view = tuple(self) + return "{0}({1!r})".format(self.__class__.__name__, view) diff --git a/src/python/grpcio/grpc/experimental/aio/_server.py b/src/python/grpcio/grpc/experimental/aio/_server.py index dc90c0a6dca..478049e5db4 100644 --- a/src/python/grpcio/grpc/experimental/aio/_server.py +++ b/src/python/grpcio/grpc/experimental/aio/_server.py @@ -13,6 +13,7 @@ # limitations under the License. """Server-side implementation of gRPC Asyncio Python.""" +import asyncio from concurrent.futures import Executor from typing import Any, Optional, Sequence @@ -40,7 +41,7 @@ class Server(_base_server.Server): options: ChannelArgumentType, maximum_concurrent_rpcs: Optional[int], compression: Optional[grpc.Compression]): - self._loop = cygrpc.grpc_aio_loop() + self._loop = asyncio.get_event_loop() if interceptors: invalid_interceptors = [ interceptor for interceptor in interceptors @@ -162,7 +163,10 @@ class Server(_base_server.Server): be safe to slightly extend the underlying Cython object's life span. """ if hasattr(self, '_server'): - cygrpc.aio_loop_schedule_coroutine(self._server.shutdown(None)) + cygrpc.schedule_coro_threadsafe( + self._server.shutdown(None), + self._loop, + ) def server(migration_thread_pool: Optional[Executor] = None, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index dd26915d14b..46cce67f77e 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -31,6 +31,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', + 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', diff --git a/src/python/grpcio_health_checking/grpc_health/v1/_async.py b/src/python/grpcio_health_checking/grpc_health/v1/_async.py index 859cadbd642..752531f5171 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/_async.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/_async.py @@ -30,7 +30,7 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): _gracefully_shutting_down: bool def __init__(self) -> None: - self._server_status = dict() + self._server_status = {"": _health_pb2.HealthCheckResponse.SERVING} self._server_watchers = collections.defaultdict(asyncio.Condition) self._gracefully_shutting_down = False diff --git a/src/python/grpcio_health_checking/grpc_health/v1/health.py b/src/python/grpcio_health_checking/grpc_health/v1/health.py index 05a16c73380..f7ee639ec8a 100644 --- a/src/python/grpcio_health_checking/grpc_health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc_health/v1/health.py @@ -85,7 +85,7 @@ class HealthServicer(_health_pb2_grpc.HealthServicer): experimental_non_blocking=True, experimental_thread_pool=None): self._lock = threading.RLock() - self._server_status = {} + self._server_status = {"": _health_pb2.HealthCheckResponse.SERVING} self._send_response_callbacks = {} self.Watch.__func__.experimental_non_blocking = experimental_non_blocking self.Watch.__func__.experimental_thread_pool = experimental_thread_pool diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 53999c3caa4..f7cd7c6b8a1 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -151,8 +151,6 @@ class TestAio(setuptools.Command): def run(self): self._add_eggs_to_path() - from grpc.experimental.aio import init_grpc_aio - init_grpc_aio() import tests loader = tests.Loader() diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index b782d80e639..01345aaca08 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -50,7 +50,6 @@ class BaseWatchTests(object): self._servicer = health.HealthServicer( experimental_non_blocking=non_blocking, experimental_thread_pool=thread_pool) - self._servicer.set('', health_pb2.HealthCheckResponse.SERVING) self._servicer.set(_SERVING_SERVICE, health_pb2.HealthCheckResponse.SERVING) self._servicer.set(_UNKNOWN_SERVICE, diff --git a/src/python/grpcio_tests/tests/interop/credentials/ca.pem b/src/python/grpcio_tests/tests/interop/credentials/ca.pem index 6c8511a73c6..49d39cd8ed5 100755 --- a/src/python/grpcio_tests/tests/interop/credentials/ca.pem +++ b/src/python/grpcio_tests/tests/interop/credentials/ca.pem @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= +MIIDWjCCAkKgAwIBAgIUWrP0VvHcy+LP6UuYNtiL9gBhD5owDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxNzE4NTk1MVoXDTMwMDMxNTE4NTk1MVowVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsGL0oXflF0LzoM+Bh+qUU9yhqzw2w8OOX5mu/iNCyUOBrqaHi7mGHx73GD01 +diNzCzvlcQqdNIH6NQSL7DTpBjca66jYT9u73vZe2MDrr1nVbuLvfu9850cdxiUO +Inv5xf8+sTHG0C+a+VAvMhsLiRjsq+lXKRJyk5zkbbsETybqpxoJ+K7CoSy3yc/k +QIY3TipwEtwkKP4hzyo6KiGd/DPexie4nBUInN3bS1BUeNZ5zeaIC2eg3bkeeW7c +qT55b+Yen6CxY0TEkzBK6AKt/WUialKMgT0wbTxRZO7kUCH3Sq6e/wXeFdJ+HvdV +LPlAg5TnMaNpRdQih/8nRFpsdwIDAQABoyAwHjAMBgNVHRMEBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAkTrKZjBrJXHps/HrjNCFPb5a +THuGPCSsepe1wkKdSp1h4HGRpLoCgcLysCJ5hZhRpHkRihhef+rFHEe60UePQO3S +CVTtdJB4CYWpcNyXOdqefrbJW5QNljxgi6Fhvs7JJkBqdXIkWXtFk2eRgOIP2Eo9 +/OHQHlYnwZFrk6sp4wPyR+A95S0toZBcyDVz7u+hOW0pGK3wviOe9lvRgj/H3Pwt +bewb0l+MhRig0/DVHamyVxrDRbqInU1/GTNCwcZkXKYFWSf92U+kIcTth24Q1gcw +eZiLl5FfrWokUNytFElXob0V0a5/kbhiLc3yWmvWqHTpqCALbVyF+rKJo2f5Kw== -----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/interop/credentials/server1.key b/src/python/grpcio_tests/tests/interop/credentials/server1.key index 143a5b87658..086462992cf 100755 --- a/src/python/grpcio_tests/tests/interop/credentials/server1.key +++ b/src/python/grpcio_tests/tests/interop/credentials/server1.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnE443EknxvxBq +6+hvn/t09hl8hx366EBYvZmVM/NC+7igXRAjiJiA/mIaCvL3MS0Iz5hBLxSGICU+ +WproA3GCIFITIwcf/ETyWj/5xpgZ4AKrLrjQmmX8mhwUajfF3UvwMJrCOVqPp67t +PtP+2kBXaqrXdvnvXR41FsIB8V7zIAuIZB6bHQhiGVlc1sgZYsE2EGG9WMmHtS86 +qkAOTjG2XyjmPTGAwhGDpYkYrpzp99IiDh4/Veai81hn0ssQkbry0XRD/Ig3jcHh +23WiriPNJ0JsbgXUSLKRPZObA9VgOLy2aXoN84IMaeK3yy+cwSYG/99w93fUZJte +MXwz4oYZAgMBAAECggEBAIVn2Ncai+4xbH0OLWckabwgyJ4IM9rDc0LIU368O1kU +koais8qP9dujAWgfoh3sGh/YGgKn96VnsZjKHlyMgF+r4TaDJn3k2rlAOWcurGlj +1qaVlsV4HiEzp7pxiDmHhWvp4672Bb6iBG+bsjCUOEk/n9o9KhZzIBluRhtxCmw5 +nw4Do7z00PTvN81260uPWSc04IrytvZUiAIx/5qxD72bij2xJ8t/I9GI8g4FtoVB +8pB6S/hJX1PZhh9VlU6Yk+TOfOVnbebG4W5138LkB835eqk3Zz0qsbc2euoi8Hxi +y1VGwQEmMQ63jXz4c6g+X55ifvUK9Jpn5E8pq+pMd7ECgYEA93lYq+Cr54K4ey5t +sWMa+ye5RqxjzgXj2Kqr55jb54VWG7wp2iGbg8FMlkQwzTJwebzDyCSatguEZLuB +gRGroRnsUOy9vBvhKPOch9bfKIl6qOgzMJB267fBVWx5ybnRbWN/I7RvMQf3k+9y +biCIVnxDLEEYyx7z85/5qxsXg/MCgYEA7wmWKtCTn032Hy9P8OL49T0X6Z8FlkDC +Rk42ygrc/MUbugq9RGUxcCxoImOG9JXUpEtUe31YDm2j+/nbvrjl6/bP2qWs0V7l +dTJl6dABP51pCw8+l4cWgBBX08Lkeen812AAFNrjmDCjX6rHjWHLJcpS18fnRRkP +V1d/AHWX7MMCgYEA6Gsw2guhp0Zf2GCcaNK5DlQab8OL4Hwrpttzo4kuTlwtqNKp +Q9H4al9qfF4Cr1TFya98+EVYf8yFRM3NLNjZpe3gwYf2EerlJj7VLcahw0KKzoN1 +QBENfwgPLRk5sDkx9VhSmcfl/diLroZdpAwtv3vo4nEoxeuGFbKTGx3Qkf0CgYEA +xyR+dcb05Ygm3w4klHQTowQ10s1H80iaUcZBgQuR1ghEtDbUPZHsoR5t1xCB02ys +DgAwLv1bChIvxvH/L6KM8ovZ2LekBX4AviWxoBxJnfz/EVau98B0b1auRN6eSC83 +FRuGldlSOW1z/nSh8ViizSYE5H5HX1qkXEippvFRE88CgYB3Bfu3YQY60ITWIShv +nNkdcbTT9eoP9suaRJjw92Ln+7ZpALYlQMKUZmJ/5uBmLs4RFwUTQruLOPL4yLTH +awADWUzs3IRr1fwn9E+zM8JVyKCnUEM3w4N5UZskGO2klashAd30hWO+knRv/y0r +uGIYs9Ek7YXlXIRVrzMwcsrt1w== -----END PRIVATE KEY----- diff --git a/src/python/grpcio_tests/tests/interop/credentials/server1.pem b/src/python/grpcio_tests/tests/interop/credentials/server1.pem index f3d43fcc5be..88244f856c6 100755 --- a/src/python/grpcio_tests/tests/interop/credentials/server1.pem +++ b/src/python/grpcio_tests/tests/interop/credentials/server1.pem @@ -1,16 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 +MIIDtDCCApygAwIBAgIUbJfTREJ6k6/+oInWhV1O1j3ZT0IwDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxODAzMTA0MloXDTMwMDMxNjAzMTA0MlowZTELMAkGA1UEBhMCVVMxETAPBgNV +BAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxl +LCBDby4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5xOONxJJ8b8Qauvob5/7dPYZfIcd+uhAWL2ZlTPz +Qvu4oF0QI4iYgP5iGgry9zEtCM+YQS8UhiAlPlqa6ANxgiBSEyMHH/xE8lo/+caY +GeACqy640Jpl/JocFGo3xd1L8DCawjlaj6eu7T7T/tpAV2qq13b5710eNRbCAfFe +8yALiGQemx0IYhlZXNbIGWLBNhBhvVjJh7UvOqpADk4xtl8o5j0xgMIRg6WJGK6c +6ffSIg4eP1XmovNYZ9LLEJG68tF0Q/yIN43B4dt1oq4jzSdCbG4F1EiykT2TmwPV +YDi8tml6DfOCDGnit8svnMEmBv/fcPd31GSbXjF8M+KGGQIDAQABo2swaTAJBgNV +HRMEAjAAMAsGA1UdDwQEAwIF4DBPBgNVHREESDBGghAqLnRlc3QuZ29vZ2xlLmZy +ghh3YXRlcnpvb2kudGVzdC5nb29nbGUuYmWCEioudGVzdC55b3V0dWJlLmNvbYcE +wKgBAzANBgkqhkiG9w0BAQsFAAOCAQEAS8hDQA8PSgipgAml7Q3/djwQ644ghWQv +C2Kb+r30RCY1EyKNhnQnIIh/OUbBZvh0M0iYsy6xqXgfDhCB93AA6j0i5cS8fkhH +Jl4RK0tSkGQ3YNY4NzXwQP/vmUgfkw8VBAZ4Y4GKxppdATjffIW+srbAmdDruIRM +wPeikgOoRrXf0LA1fi4TqxARzeRwenQpayNfGHTvVF9aJkl8HoaMunTAdG5pIVcr +9GKi/gEMpXUJbbVv3U5frX1Wo4CFo+rZWJ/LyCMeb0jciNLxSdMwj/E/ZuExlyeZ +gc9ctPjSMvgSyXEKv6Vwobleeg88V2ZgzenziORoWj4KszG/lbQZvg== -----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/qps/BUILD.bazel b/src/python/grpcio_tests/tests/qps/BUILD.bazel index c4f5d4dbd1a..bedb98cd437 100644 --- a/src/python/grpcio_tests/tests/qps/BUILD.bazel +++ b/src/python/grpcio_tests/tests/qps/BUILD.bazel @@ -25,3 +25,66 @@ py_library( "//src/proto/grpc/testing:stats_py_pb2", ], ) + +py_library( + name = "benchmark_client", + srcs = ["benchmark_client.py"], + srcs_version = "PY2AND3", + deps = [ + "//src/proto/grpc/testing:benchmark_service_py_pb2_grpc", + "//src/proto/grpc/testing:py_messages_proto", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:resources", + "//src/python/grpcio_tests/tests/unit:test_common", + ], +) + +py_library( + name = "benchmark_server", + srcs = ["benchmark_server.py"], + srcs_version = "PY2AND3", + deps = [ + "//src/proto/grpc/testing:benchmark_service_py_pb2_grpc", + "//src/proto/grpc/testing:py_messages_proto", + ], +) + +py_library( + name = "client_runner", + srcs = ["client_runner.py"], + srcs_version = "PY2AND3", +) + +py_library( + name = "worker_server", + srcs = ["worker_server.py"], + srcs_version = "PY2AND3", + deps = [ + ":benchmark_client", + ":benchmark_server", + ":client_runner", + ":histogram", + "//src/proto/grpc/core:stats_py_pb2", + "//src/proto/grpc/testing:benchmark_service_py_pb2_grpc", + "//src/proto/grpc/testing:control_py_pb2", + "//src/proto/grpc/testing:payloads_py_pb2", + "//src/proto/grpc/testing:stats_py_pb2", + "//src/proto/grpc/testing:worker_service_py_pb2_grpc", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:resources", + "//src/python/grpcio_tests/tests/unit:test_common", + ], +) + +py_binary( + name = "qps_worker", + srcs = ["qps_worker.py"], + imports = ["../.."], + srcs_version = "PY2AND3", + deps = [ + ":worker_server", + "//src/proto/grpc/testing:worker_service_py_pb2_grpc", + "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:test_common", + ], +) diff --git a/src/python/grpcio_tests/tests/qps/benchmark_client.py b/src/python/grpcio_tests/tests/qps/benchmark_client.py index 78d3d60efa3..17835e7c0db 100644 --- a/src/python/grpcio_tests/tests/qps/benchmark_client.py +++ b/src/python/grpcio_tests/tests/qps/benchmark_client.py @@ -61,14 +61,16 @@ class BenchmarkClient: self._stub = benchmark_service_pb2_grpc.BenchmarkServiceStub( channel) payload = messages_pb2.Payload( - body='\0' * config.payload_config.simple_params.req_size) + body=bytes(b'\0' * + config.payload_config.simple_params.req_size)) self._request = messages_pb2.SimpleRequest( payload=payload, response_size=config.payload_config.simple_params.resp_size) else: self._generic = True self._stub = GenericStub(channel) - self._request = '\0' * config.payload_config.bytebuf_params.req_size + self._request = bytes(b'\0' * + config.payload_config.bytebuf_params.req_size) self._hist = hist self._response_callbacks = [] diff --git a/src/python/grpcio_tests/tests/qps/benchmark_server.py b/src/python/grpcio_tests/tests/qps/benchmark_server.py index 48586d9aa94..75280bd7719 100644 --- a/src/python/grpcio_tests/tests/qps/benchmark_server.py +++ b/src/python/grpcio_tests/tests/qps/benchmark_server.py @@ -20,12 +20,12 @@ class BenchmarkServer(benchmark_service_pb2_grpc.BenchmarkServiceServicer): """Synchronous Server implementation for the Benchmark service.""" def UnaryCall(self, request, context): - payload = messages_pb2.Payload(body='\0' * request.response_size) + payload = messages_pb2.Payload(body=b'\0' * request.response_size) return messages_pb2.SimpleResponse(payload=payload) def StreamingCall(self, request_iterator, context): for request in request_iterator: - payload = messages_pb2.Payload(body='\0' * request.response_size) + payload = messages_pb2.Payload(body=b'\0' * request.response_size) yield messages_pb2.SimpleResponse(payload=payload) @@ -34,7 +34,7 @@ class GenericBenchmarkServer(benchmark_service_pb2_grpc.BenchmarkServiceServicer """Generic Server implementation for the Benchmark service.""" def __init__(self, resp_size): - self._response = '\0' * resp_size + self._response = b'\0' * resp_size def UnaryCall(self, request, context): return self._response diff --git a/src/python/grpcio_tests/tests/unit/credentials/ca.pem b/src/python/grpcio_tests/tests/unit/credentials/ca.pem index 6c8511a73c6..49d39cd8ed5 100755 --- a/src/python/grpcio_tests/tests/unit/credentials/ca.pem +++ b/src/python/grpcio_tests/tests/unit/credentials/ca.pem @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= +MIIDWjCCAkKgAwIBAgIUWrP0VvHcy+LP6UuYNtiL9gBhD5owDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxNzE4NTk1MVoXDTMwMDMxNTE4NTk1MVowVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsGL0oXflF0LzoM+Bh+qUU9yhqzw2w8OOX5mu/iNCyUOBrqaHi7mGHx73GD01 +diNzCzvlcQqdNIH6NQSL7DTpBjca66jYT9u73vZe2MDrr1nVbuLvfu9850cdxiUO +Inv5xf8+sTHG0C+a+VAvMhsLiRjsq+lXKRJyk5zkbbsETybqpxoJ+K7CoSy3yc/k +QIY3TipwEtwkKP4hzyo6KiGd/DPexie4nBUInN3bS1BUeNZ5zeaIC2eg3bkeeW7c +qT55b+Yen6CxY0TEkzBK6AKt/WUialKMgT0wbTxRZO7kUCH3Sq6e/wXeFdJ+HvdV +LPlAg5TnMaNpRdQih/8nRFpsdwIDAQABoyAwHjAMBgNVHRMEBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAkTrKZjBrJXHps/HrjNCFPb5a +THuGPCSsepe1wkKdSp1h4HGRpLoCgcLysCJ5hZhRpHkRihhef+rFHEe60UePQO3S +CVTtdJB4CYWpcNyXOdqefrbJW5QNljxgi6Fhvs7JJkBqdXIkWXtFk2eRgOIP2Eo9 +/OHQHlYnwZFrk6sp4wPyR+A95S0toZBcyDVz7u+hOW0pGK3wviOe9lvRgj/H3Pwt +bewb0l+MhRig0/DVHamyVxrDRbqInU1/GTNCwcZkXKYFWSf92U+kIcTth24Q1gcw +eZiLl5FfrWokUNytFElXob0V0a5/kbhiLc3yWmvWqHTpqCALbVyF+rKJo2f5Kw== -----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/server1.key b/src/python/grpcio_tests/tests/unit/credentials/server1.key index 143a5b87658..086462992cf 100755 --- a/src/python/grpcio_tests/tests/unit/credentials/server1.key +++ b/src/python/grpcio_tests/tests/unit/credentials/server1.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnE443EknxvxBq +6+hvn/t09hl8hx366EBYvZmVM/NC+7igXRAjiJiA/mIaCvL3MS0Iz5hBLxSGICU+ +WproA3GCIFITIwcf/ETyWj/5xpgZ4AKrLrjQmmX8mhwUajfF3UvwMJrCOVqPp67t +PtP+2kBXaqrXdvnvXR41FsIB8V7zIAuIZB6bHQhiGVlc1sgZYsE2EGG9WMmHtS86 +qkAOTjG2XyjmPTGAwhGDpYkYrpzp99IiDh4/Veai81hn0ssQkbry0XRD/Ig3jcHh +23WiriPNJ0JsbgXUSLKRPZObA9VgOLy2aXoN84IMaeK3yy+cwSYG/99w93fUZJte +MXwz4oYZAgMBAAECggEBAIVn2Ncai+4xbH0OLWckabwgyJ4IM9rDc0LIU368O1kU +koais8qP9dujAWgfoh3sGh/YGgKn96VnsZjKHlyMgF+r4TaDJn3k2rlAOWcurGlj +1qaVlsV4HiEzp7pxiDmHhWvp4672Bb6iBG+bsjCUOEk/n9o9KhZzIBluRhtxCmw5 +nw4Do7z00PTvN81260uPWSc04IrytvZUiAIx/5qxD72bij2xJ8t/I9GI8g4FtoVB +8pB6S/hJX1PZhh9VlU6Yk+TOfOVnbebG4W5138LkB835eqk3Zz0qsbc2euoi8Hxi +y1VGwQEmMQ63jXz4c6g+X55ifvUK9Jpn5E8pq+pMd7ECgYEA93lYq+Cr54K4ey5t +sWMa+ye5RqxjzgXj2Kqr55jb54VWG7wp2iGbg8FMlkQwzTJwebzDyCSatguEZLuB +gRGroRnsUOy9vBvhKPOch9bfKIl6qOgzMJB267fBVWx5ybnRbWN/I7RvMQf3k+9y +biCIVnxDLEEYyx7z85/5qxsXg/MCgYEA7wmWKtCTn032Hy9P8OL49T0X6Z8FlkDC +Rk42ygrc/MUbugq9RGUxcCxoImOG9JXUpEtUe31YDm2j+/nbvrjl6/bP2qWs0V7l +dTJl6dABP51pCw8+l4cWgBBX08Lkeen812AAFNrjmDCjX6rHjWHLJcpS18fnRRkP +V1d/AHWX7MMCgYEA6Gsw2guhp0Zf2GCcaNK5DlQab8OL4Hwrpttzo4kuTlwtqNKp +Q9H4al9qfF4Cr1TFya98+EVYf8yFRM3NLNjZpe3gwYf2EerlJj7VLcahw0KKzoN1 +QBENfwgPLRk5sDkx9VhSmcfl/diLroZdpAwtv3vo4nEoxeuGFbKTGx3Qkf0CgYEA +xyR+dcb05Ygm3w4klHQTowQ10s1H80iaUcZBgQuR1ghEtDbUPZHsoR5t1xCB02ys +DgAwLv1bChIvxvH/L6KM8ovZ2LekBX4AviWxoBxJnfz/EVau98B0b1auRN6eSC83 +FRuGldlSOW1z/nSh8ViizSYE5H5HX1qkXEippvFRE88CgYB3Bfu3YQY60ITWIShv +nNkdcbTT9eoP9suaRJjw92Ln+7ZpALYlQMKUZmJ/5uBmLs4RFwUTQruLOPL4yLTH +awADWUzs3IRr1fwn9E+zM8JVyKCnUEM3w4N5UZskGO2klashAd30hWO+knRv/y0r +uGIYs9Ek7YXlXIRVrzMwcsrt1w== -----END PRIVATE KEY----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/server1.pem b/src/python/grpcio_tests/tests/unit/credentials/server1.pem index f3d43fcc5be..88244f856c6 100755 --- a/src/python/grpcio_tests/tests/unit/credentials/server1.pem +++ b/src/python/grpcio_tests/tests/unit/credentials/server1.pem @@ -1,16 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 +MIIDtDCCApygAwIBAgIUbJfTREJ6k6/+oInWhV1O1j3ZT0IwDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxODAzMTA0MloXDTMwMDMxNjAzMTA0MlowZTELMAkGA1UEBhMCVVMxETAPBgNV +BAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxl +LCBDby4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5xOONxJJ8b8Qauvob5/7dPYZfIcd+uhAWL2ZlTPz +Qvu4oF0QI4iYgP5iGgry9zEtCM+YQS8UhiAlPlqa6ANxgiBSEyMHH/xE8lo/+caY +GeACqy640Jpl/JocFGo3xd1L8DCawjlaj6eu7T7T/tpAV2qq13b5710eNRbCAfFe +8yALiGQemx0IYhlZXNbIGWLBNhBhvVjJh7UvOqpADk4xtl8o5j0xgMIRg6WJGK6c +6ffSIg4eP1XmovNYZ9LLEJG68tF0Q/yIN43B4dt1oq4jzSdCbG4F1EiykT2TmwPV +YDi8tml6DfOCDGnit8svnMEmBv/fcPd31GSbXjF8M+KGGQIDAQABo2swaTAJBgNV +HRMEAjAAMAsGA1UdDwQEAwIF4DBPBgNVHREESDBGghAqLnRlc3QuZ29vZ2xlLmZy +ghh3YXRlcnpvb2kudGVzdC5nb29nbGUuYmWCEioudGVzdC55b3V0dWJlLmNvbYcE +wKgBAzANBgkqhkiG9w0BAQsFAAOCAQEAS8hDQA8PSgipgAml7Q3/djwQ644ghWQv +C2Kb+r30RCY1EyKNhnQnIIh/OUbBZvh0M0iYsy6xqXgfDhCB93AA6j0i5cS8fkhH +Jl4RK0tSkGQ3YNY4NzXwQP/vmUgfkw8VBAZ4Y4GKxppdATjffIW+srbAmdDruIRM +wPeikgOoRrXf0LA1fi4TqxARzeRwenQpayNfGHTvVF9aJkl8HoaMunTAdG5pIVcr +9GKi/gEMpXUJbbVv3U5frX1Wo4CFo+rZWJ/LyCMeb0jciNLxSdMwj/E/ZuExlyeZ +gc9ctPjSMvgSyXEKv6Vwobleeg88V2ZgzenziORoWj4KszG/lbQZvg== -----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests_aio/benchmark/server.py b/src/python/grpcio_tests/tests_aio/benchmark/server.py index 05479a2997d..561298a626b 100644 --- a/src/python/grpcio_tests/tests_aio/benchmark/server.py +++ b/src/python/grpcio_tests/tests_aio/benchmark/server.py @@ -36,7 +36,6 @@ async def _start_async_server(): def main(): - aio.init_grpc_aio() loop = asyncio.get_event_loop() loop.create_task(_start_async_server()) loop.run_forever() diff --git a/src/python/grpcio_tests/tests_aio/benchmark/worker.py b/src/python/grpcio_tests/tests_aio/benchmark/worker.py index 94651b55057..dc16f050872 100644 --- a/src/python/grpcio_tests/tests_aio/benchmark/worker.py +++ b/src/python/grpcio_tests/tests_aio/benchmark/worker.py @@ -23,7 +23,6 @@ from tests_aio.benchmark import worker_servicer async def run_worker_server(port: int) -> None: - aio.init_grpc_aio() server = aio.server() servicer = worker_servicer.WorkerServicer() @@ -53,6 +52,8 @@ if __name__ == '__main__': if args.uvloop: import uvloop - uvloop.install() + asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) + loop = uvloop.new_event_loop() + asyncio.set_event_loop(loop) asyncio.get_event_loop().run_until_complete(run_worker_server(args.port)) diff --git a/src/python/grpcio_tests/tests_aio/health_check/health_servicer_test.py b/src/python/grpcio_tests/tests_aio/health_check/health_servicer_test.py index 71166a2beff..ac6c84b2f54 100644 --- a/src/python/grpcio_tests/tests_aio/health_check/health_servicer_test.py +++ b/src/python/grpcio_tests/tests_aio/health_check/health_servicer_test.py @@ -47,8 +47,6 @@ class HealthServicerTest(AioTestBase): async def setUp(self): self._servicer = health.aio.HealthServicer() - await self._servicer.set(health.OVERALL_HEALTH, - health_pb2.HealthCheckResponse.SERVING) await self._servicer.set(_SERVING_SERVICE, health_pb2.HealthCheckResponse.SERVING) await self._servicer.set(_UNKNOWN_SERVICE, diff --git a/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel b/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel index b5bbdc6df4e..f67ad35cca7 100644 --- a/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel +++ b/src/python/grpcio_tests/tests_aio/interop/BUILD.bazel @@ -56,6 +56,7 @@ py_binary( python_version = "PY3", deps = [ "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/interop:resources", "//src/python/grpcio_tests/tests/interop:server", "//src/python/grpcio_tests/tests_aio/unit:_test_server", ], @@ -70,5 +71,6 @@ py_binary( ":methods", "//src/python/grpcio/grpc:grpcio", "//src/python/grpcio_tests/tests/interop:client", + "//src/python/grpcio_tests/tests/interop:resources", ], ) diff --git a/src/python/grpcio_tests/tests_aio/interop/client.py b/src/python/grpcio_tests/tests_aio/interop/client.py index 905effa45bf..89793f94054 100644 --- a/src/python/grpcio_tests/tests_aio/interop/client.py +++ b/src/python/grpcio_tests/tests_aio/interop/client.py @@ -47,7 +47,6 @@ def _test_case_from_arg(test_case_arg): async def test_interoperability(): - aio.init_grpc_aio() args = interop_client_lib.parse_interop_client_args() channel = _create_channel(args) diff --git a/src/python/grpcio_tests/tests_aio/interop/local_interop_test.py b/src/python/grpcio_tests/tests_aio/interop/local_interop_test.py index c8b6083ae39..0db15be3a94 100644 --- a/src/python/grpcio_tests/tests_aio/interop/local_interop_test.py +++ b/src/python/grpcio_tests/tests_aio/interop/local_interop_test.py @@ -64,7 +64,6 @@ class InteropTestCaseMixin: await methods.test_interoperability( methods.TestCase.CANCEL_AFTER_FIRST_RESPONSE, self._stub, None) - @unittest.skip('TODO(https://github.com/grpc/grpc/issues/21707)') async def test_timeout_on_sleeping_server(self): await methods.test_interoperability( methods.TestCase.TIMEOUT_ON_SLEEPING_SERVER, self._stub, None) diff --git a/src/python/grpcio_tests/tests_aio/interop/methods.py b/src/python/grpcio_tests/tests_aio/interop/methods.py index 7c5c1edfd2b..019b3bca894 100644 --- a/src/python/grpcio_tests/tests_aio/interop/methods.py +++ b/src/python/grpcio_tests/tests_aio/interop/methods.py @@ -15,8 +15,9 @@ import argparse import asyncio -import enum import collections +import datetime +import enum import inspect import json import os @@ -220,12 +221,15 @@ async def _cancel_after_first_response(stub: test_pb2_grpc.TestServiceStub): async def _timeout_on_sleeping_server(stub: test_pb2_grpc.TestServiceStub): request_payload_size = 27182 + time_limit = datetime.timedelta(seconds=1) - call = stub.FullDuplexCall(timeout=0.001) + call = stub.FullDuplexCall(timeout=time_limit.total_seconds()) request = messages_pb2.StreamingOutputCallRequest( response_type=messages_pb2.COMPRESSABLE, - payload=messages_pb2.Payload(body=b'\x00' * request_payload_size)) + payload=messages_pb2.Payload(body=b'\x00' * request_payload_size), + response_parameters=(messages_pb2.ResponseParameters( + interval_us=int(time_limit.total_seconds() * 2 * 10**6)),)) await call.write(request) await call.done_writing() try: diff --git a/src/python/grpcio_tests/tests_aio/interop/server.py b/src/python/grpcio_tests/tests_aio/interop/server.py index 5a5180075a3..06a6c51d13a 100644 --- a/src/python/grpcio_tests/tests_aio/interop/server.py +++ b/src/python/grpcio_tests/tests_aio/interop/server.py @@ -18,7 +18,6 @@ import argparse import logging import grpc -from grpc.experimental.aio import init_grpc_aio from tests.interop import server as interop_server_lib from tests_aio.unit import _test_server @@ -29,8 +28,6 @@ _LOGGER.setLevel(logging.DEBUG) async def serve(): - init_grpc_aio() - args = interop_server_lib.parse_interop_server_arguments() if args.use_tls: diff --git a/src/python/grpcio_tests/tests_aio/tests.json b/src/python/grpcio_tests/tests_aio/tests.json index 6ee095ae3d8..84dbf02b937 100644 --- a/src/python/grpcio_tests/tests_aio/tests.json +++ b/src/python/grpcio_tests/tests_aio/tests.json @@ -3,6 +3,7 @@ "health_check.health_servicer_test.HealthServicerTest", "interop.local_interop_test.InsecureLocalInteropTest", "interop.local_interop_test.SecureLocalInteropTest", + "unit._metadata_test.TestTypeMetadata", "unit.abort_test.TestAbort", "unit.aio_rpc_error_test.TestAioRpcError", "unit.call_test.TestStreamStreamCall", @@ -15,12 +16,15 @@ "unit.client_interceptor_test.TestInterceptedUnaryUnaryCall", "unit.client_interceptor_test.TestUnaryUnaryClientInterceptor", "unit.close_channel_test.TestCloseChannel", + "unit.compatibility_test.TestCompatibility", "unit.compression_test.TestCompression", "unit.connectivity_test.TestConnectivityState", "unit.done_callback_test.TestDoneCallback", - "unit.init_test.TestInsecureChannel", - "unit.init_test.TestSecureChannel", + "unit.init_test.TestChannel", "unit.metadata_test.TestMetadata", + "unit.secure_call_test.TestStreamStreamSecureCall", + "unit.secure_call_test.TestUnaryStreamSecureCall", + "unit.secure_call_test.TestUnaryUnarySecureCall", "unit.server_interceptor_test.TestServerInterceptor", "unit.server_test.TestServer", "unit.timeout_test.TestTimeout", diff --git a/src/python/grpcio_tests/tests_aio/unit/BUILD.bazel b/src/python/grpcio_tests/tests_aio/unit/BUILD.bazel index 1e6dd4720f6..1847e9cff6e 100644 --- a/src/python/grpcio_tests/tests_aio/unit/BUILD.bazel +++ b/src/python/grpcio_tests/tests_aio/unit/BUILD.bazel @@ -41,6 +41,7 @@ py_library( "//src/proto/grpc/testing:py_messages_proto", "//src/proto/grpc/testing:test_py_pb2_grpc", "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:resources", ], ) @@ -50,6 +51,11 @@ py_library( srcs_version = "PY3", ) +_FLAKY_TESTS = [ + # TODO(https://github.com/grpc/grpc/issues/22347) remove from this list. + "channel_argument_test.py", +] + [ py_test( name = test_file_name[:-3], @@ -58,6 +64,7 @@ py_library( data = [ "//src/python/grpcio_tests/tests/unit/credentials", ], + flaky = test_file_name in _FLAKY_TESTS, imports = ["../../"], main = test_file_name, python_version = "PY3", @@ -70,6 +77,7 @@ py_library( "//src/proto/grpc/testing:benchmark_service_py_pb2_grpc", "//src/proto/grpc/testing:py_messages_proto", "//src/python/grpcio/grpc:grpcio", + "//src/python/grpcio_tests/tests/unit:resources", "//src/python/grpcio_tests/tests/unit/framework/common", "@six", ], diff --git a/src/python/grpcio_tests/tests_aio/unit/_metadata_test.py b/src/python/grpcio_tests/tests_aio/unit/_metadata_test.py new file mode 100644 index 00000000000..dda58c5ed53 --- /dev/null +++ b/src/python/grpcio_tests/tests_aio/unit/_metadata_test.py @@ -0,0 +1,125 @@ +# Copyright 2020 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. +"""Tests for the metadata abstraction that's used in the asynchronous driver.""" +import logging +import unittest + +from grpc.experimental.aio import Metadata + + +class TestTypeMetadata(unittest.TestCase): + """Tests for the metadata type""" + + _DEFAULT_DATA = (("key1", "value1"), ("key2", "value2")) + _MULTI_ENTRY_DATA = (("key1", "value1"), ("key1", "other value 1"), + ("key2", "value2")) + + def test_init_metadata(self): + test_cases = { + "emtpy": (), + "with-single-data": self._DEFAULT_DATA, + "with-multi-data": self._MULTI_ENTRY_DATA, + } + for case, args in test_cases.items(): + with self.subTest(case=case): + metadata = Metadata(*args) + self.assertEqual(len(metadata), len(args)) + + def test_get_item(self): + metadata = Metadata(("key", "value1"), ("key", "value2"), + ("key2", "other value")) + self.assertEqual(metadata["key"], "value1") + self.assertEqual(metadata["key2"], "other value") + self.assertEqual(metadata.get("key"), "value1") + self.assertEqual(metadata.get("key2"), "other value") + + with self.assertRaises(KeyError): + metadata["key not found"] + self.assertIsNone(metadata.get("key not found")) + + def test_add_value(self): + metadata = Metadata() + metadata.add("key", "value") + metadata.add("key", "second value") + metadata.add("key2", "value2") + + self.assertEqual(metadata["key"], "value") + self.assertEqual(metadata["key2"], "value2") + + def test_get_all_items(self): + metadata = Metadata(*self._MULTI_ENTRY_DATA) + self.assertEqual(metadata.get_all("key1"), ["value1", "other value 1"]) + self.assertEqual(metadata.get_all("key2"), ["value2"]) + self.assertEqual(metadata.get_all("non existing key"), []) + + def test_container(self): + metadata = Metadata(*self._MULTI_ENTRY_DATA) + self.assertIn("key1", metadata) + + def test_equals(self): + metadata = Metadata() + for key, value in self._DEFAULT_DATA: + metadata.add(key, value) + metadata2 = Metadata(*self._DEFAULT_DATA) + + self.assertEqual(metadata, metadata2) + self.assertNotEqual(metadata, "foo") + + def test_repr(self): + metadata = Metadata(*self._DEFAULT_DATA) + expected = "Metadata({0!r})".format(self._DEFAULT_DATA) + self.assertEqual(repr(metadata), expected) + + def test_set(self): + metadata = Metadata(*self._MULTI_ENTRY_DATA) + override_value = "override value" + for _ in range(3): + metadata["key1"] = override_value + + self.assertEqual(metadata["key1"], override_value) + self.assertEqual(metadata.get_all("key1"), + [override_value, "other value 1"]) + + empty_metadata = Metadata() + for _ in range(3): + empty_metadata["key"] = override_value + + self.assertEqual(empty_metadata["key"], override_value) + self.assertEqual(empty_metadata.get_all("key"), [override_value]) + + def test_set_all(self): + metadata = Metadata(*self._DEFAULT_DATA) + metadata.set_all("key", ["value1", b"new value 2"]) + + self.assertEqual(metadata["key"], "value1") + self.assertEqual(metadata.get_all("key"), ["value1", b"new value 2"]) + + def test_delete_values(self): + metadata = Metadata(*self._MULTI_ENTRY_DATA) + del metadata["key1"] + self.assertEqual(metadata.get("key1"), "other value 1") + + metadata.delete_all("key1") + self.assertNotIn("key1", metadata) + + metadata.delete_all("key2") + self.assertEqual(len(metadata), 0) + + with self.assertRaises(KeyError): + del metadata["other key"] + + +if __name__ == '__main__': + logging.basicConfig() + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/_test_base.py b/src/python/grpcio_tests/tests_aio/unit/_test_base.py index d9284585c4b..82ec7b456ad 100644 --- a/src/python/grpcio_tests/tests_aio/unit/_test_base.py +++ b/src/python/grpcio_tests/tests_aio/unit/_test_base.py @@ -46,10 +46,13 @@ def _get_default_loop(debug=True): # NOTE(gnossen) this test class can also be implemented with metaclass. class AioTestBase(unittest.TestCase): + # NOTE(lidi) We need to pick a loop for entire testing phase, otherwise it + # will trigger create new loops in new threads, leads to deadlock. + _TEST_LOOP = _get_default_loop() @property def loop(self): - return _get_default_loop() + return self._TEST_LOOP def __getattribute__(self, name): """Overrides the loading logic to support coroutine functions.""" @@ -58,7 +61,7 @@ class AioTestBase(unittest.TestCase): # If possible, converts the coroutine into a sync function. if name.startswith('test_') or name in _COROUTINE_FUNCTION_ALLOWLIST: if asyncio.iscoroutinefunction(attr): - return _async_to_sync_decorator(attr, _get_default_loop()) + return _async_to_sync_decorator(attr, self._TEST_LOOP) # For other attributes, let them pass. return attr diff --git a/src/python/grpcio_tests/tests_aio/unit/_test_server.py b/src/python/grpcio_tests/tests_aio/unit/_test_server.py index 7c8afa8ff5c..2396608e5cc 100644 --- a/src/python/grpcio_tests/tests_aio/unit/_test_server.py +++ b/src/python/grpcio_tests/tests_aio/unit/_test_server.py @@ -17,6 +17,7 @@ import datetime import grpc from grpc.experimental import aio +from tests.unit import resources from src.proto.grpc.testing import empty_pb2, messages_pb2, test_pb2_grpc from tests_aio.unit import _constants @@ -129,8 +130,9 @@ async def start_test_server(port=0, if secure: if server_credentials is None: - server_credentials = grpc.local_server_credentials( - grpc.LocalConnectionType.LOCAL_TCP) + server_credentials = grpc.ssl_server_credentials([ + (resources.private_key(), resources.certificate_chain()) + ]) port = server.add_secure_port('[::]:%d' % port, server_credentials) else: port = server.add_insecure_port('[::]:%d' % port) diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py index f845e078684..f64f4e44802 100644 --- a/src/python/grpcio_tests/tests_aio/unit/call_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py @@ -14,7 +14,6 @@ """Tests behavior of the Call classes.""" import asyncio -import datetime import logging import unittest @@ -24,6 +23,8 @@ from grpc.experimental import aio from src.proto.grpc.testing import messages_pb2, test_pb2_grpc from tests.unit.framework.common import test_constants from tests_aio.unit._test_base import AioTestBase +from tests.unit import resources + from tests_aio.unit._test_server import start_test_server _NUM_STREAM_RESPONSES = 5 @@ -55,7 +56,7 @@ class TestUnaryUnaryCall(_MulticallableTestMixin, AioTestBase): self.assertTrue(str(call) is not None) self.assertTrue(repr(call) is not None) - response = await call + await call self.assertTrue(str(call) is not None) self.assertTrue(repr(call) is not None) @@ -202,6 +203,17 @@ class TestUnaryUnaryCall(_MulticallableTestMixin, AioTestBase): with self.assertRaises(asyncio.CancelledError): await task + async def test_passing_credentials_fails_over_insecure_channel(self): + call_credentials = grpc.composite_call_credentials( + grpc.access_token_call_credentials("abc"), + grpc.access_token_call_credentials("def"), + ) + with self.assertRaisesRegex( + aio.UsageError, + "Call credentials are only valid on secure channels"): + self._stub.UnaryCall(messages_pb2.SimpleRequest(), + credentials=call_credentials) + class TestUnaryStreamCall(_MulticallableTestMixin, AioTestBase): @@ -410,33 +422,6 @@ class TestUnaryStreamCall(_MulticallableTestMixin, AioTestBase): with self.assertRaises(asyncio.CancelledError): await task - def test_call_credentials(self): - - class DummyAuth(grpc.AuthMetadataPlugin): - - def __call__(self, context, callback): - signature = context.method_name[::-1] - callback((("test", signature),), None) - - async def coro(): - server_target, _ = await start_test_server(secure=False) # pylint: disable=unused-variable - - async with aio.insecure_channel(server_target) as channel: - hi = channel.unary_unary('/grpc.testing.TestService/UnaryCall', - request_serializer=messages_pb2. - SimpleRequest.SerializeToString, - response_deserializer=messages_pb2. - SimpleResponse.FromString) - call_credentials = grpc.metadata_call_credentials(DummyAuth()) - call = hi(messages_pb2.SimpleRequest(), - credentials=call_credentials) - response = await call - - self.assertIsInstance(response, messages_pb2.SimpleResponse) - self.assertEqual(await call.code(), grpc.StatusCode.OK) - - self.loop.run_until_complete(coro()) - async def test_time_remaining(self): request = messages_pb2.StreamingOutputCallRequest() # First message comes back immediately @@ -755,5 +740,5 @@ class TestStreamStreamCall(_MulticallableTestMixin, AioTestBase): if __name__ == '__main__': - logging.basicConfig() + logging.basicConfig(level=logging.DEBUG) unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/channel_test.py b/src/python/grpcio_tests/tests_aio/unit/channel_test.py index 10949ac180c..58cd555491d 100644 --- a/src/python/grpcio_tests/tests_aio/unit/channel_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/channel_test.py @@ -226,5 +226,5 @@ class TestChannel(AioTestBase): if __name__ == '__main__': - logging.basicConfig(level=logging.INFO) + logging.basicConfig(level=logging.DEBUG) unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/client_interceptor_test.py b/src/python/grpcio_tests/tests_aio/unit/client_interceptor_test.py index 9fa08a78806..8f5a356ca4a 100644 --- a/src/python/grpcio_tests/tests_aio/unit/client_interceptor_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/client_interceptor_test.py @@ -686,5 +686,5 @@ class TestInterceptedUnaryUnaryCall(AioTestBase): if __name__ == '__main__': - logging.basicConfig() + logging.basicConfig(level=logging.DEBUG) unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/close_channel_test.py b/src/python/grpcio_tests/tests_aio/unit/close_channel_test.py index f05c74392d9..1e10074c47c 100644 --- a/src/python/grpcio_tests/tests_aio/unit/close_channel_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/close_channel_test.py @@ -134,5 +134,5 @@ class TestCloseChannel(AioTestBase): if __name__ == '__main__': - logging.basicConfig(level=logging.INFO) + logging.basicConfig(level=logging.DEBUG) unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/compatibility_test.py b/src/python/grpcio_tests/tests_aio/unit/compatibility_test.py new file mode 100644 index 00000000000..e3d85e70e69 --- /dev/null +++ b/src/python/grpcio_tests/tests_aio/unit/compatibility_test.py @@ -0,0 +1,208 @@ +# Copyright 2020 The 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. +"""Testing the compatibility between AsyncIO stack and the old stack.""" + +import asyncio +import logging +import os +import random +import threading +import unittest +from concurrent.futures import ThreadPoolExecutor +from typing import Callable, Sequence, Tuple + +import grpc +from grpc.experimental import aio + +from src.proto.grpc.testing import messages_pb2, test_pb2_grpc +from tests.unit.framework.common import test_constants +from tests_aio.unit._test_base import AioTestBase +from tests_aio.unit._test_server import start_test_server + +_NUM_STREAM_RESPONSES = 5 +_REQUEST_PAYLOAD_SIZE = 7 +_RESPONSE_PAYLOAD_SIZE = 42 + + +def _unique_options() -> Sequence[Tuple[str, float]]: + return (('iv', random.random()),) + + +@unittest.skipIf( + os.environ.get('GRPC_ASYNCIO_ENGINE', '').lower() != 'poller', + 'Compatible mode needs POLLER completion queue.') +class TestCompatibility(AioTestBase): + + async def setUp(self): + address, self._async_server = await start_test_server() + # Create async stub + self._async_channel = aio.insecure_channel(address, + options=_unique_options()) + self._async_stub = test_pb2_grpc.TestServiceStub(self._async_channel) + + # Create sync stub + self._sync_channel = grpc.insecure_channel(address, + options=_unique_options()) + self._sync_stub = test_pb2_grpc.TestServiceStub(self._sync_channel) + + async def tearDown(self): + self._sync_channel.close() + await self._async_channel.close() + await self._async_server.stop(None) + + async def _run_in_another_thread(self, func: Callable[[], None]): + work_done = asyncio.Event(loop=self.loop) + + def thread_work(): + func() + self.loop.call_soon_threadsafe(work_done.set) + + thread = threading.Thread(target=thread_work, daemon=True) + thread.start() + await work_done.wait() + thread.join() + + async def test_unary_unary(self): + # Calling async API in this thread + await self._async_stub.UnaryCall(messages_pb2.SimpleRequest(), + timeout=test_constants.LONG_TIMEOUT) + + # Calling sync API in a different thread + def sync_work() -> None: + response, call = self._sync_stub.UnaryCall.with_call( + messages_pb2.SimpleRequest(), + timeout=test_constants.LONG_TIMEOUT) + self.assertIsInstance(response, messages_pb2.SimpleResponse) + self.assertEqual(grpc.StatusCode.OK, call.code()) + + await self._run_in_another_thread(sync_work) + + async def test_unary_stream(self): + request = messages_pb2.StreamingOutputCallRequest() + for _ in range(_NUM_STREAM_RESPONSES): + request.response_parameters.append( + messages_pb2.ResponseParameters(size=_RESPONSE_PAYLOAD_SIZE)) + + # Calling async API in this thread + call = self._async_stub.StreamingOutputCall(request) + + for _ in range(_NUM_STREAM_RESPONSES): + await call.read() + self.assertEqual(grpc.StatusCode.OK, await call.code()) + + # Calling sync API in a different thread + def sync_work() -> None: + response_iterator = self._sync_stub.StreamingOutputCall(request) + for response in response_iterator: + assert _RESPONSE_PAYLOAD_SIZE == len(response.payload.body) + self.assertEqual(grpc.StatusCode.OK, response_iterator.code()) + + await self._run_in_another_thread(sync_work) + + async def test_stream_unary(self): + payload = messages_pb2.Payload(body=b'\0' * _REQUEST_PAYLOAD_SIZE) + request = messages_pb2.StreamingInputCallRequest(payload=payload) + + # Calling async API in this thread + async def gen(): + for _ in range(_NUM_STREAM_RESPONSES): + yield request + + response = await self._async_stub.StreamingInputCall(gen()) + self.assertEqual(_NUM_STREAM_RESPONSES * _REQUEST_PAYLOAD_SIZE, + response.aggregated_payload_size) + + # Calling sync API in a different thread + def sync_work() -> None: + response = self._sync_stub.StreamingInputCall( + iter([request] * _NUM_STREAM_RESPONSES)) + self.assertEqual(_NUM_STREAM_RESPONSES * _REQUEST_PAYLOAD_SIZE, + response.aggregated_payload_size) + + await self._run_in_another_thread(sync_work) + + async def test_stream_stream(self): + request = messages_pb2.StreamingOutputCallRequest() + request.response_parameters.append( + messages_pb2.ResponseParameters(size=_RESPONSE_PAYLOAD_SIZE)) + + # Calling async API in this thread + call = self._async_stub.FullDuplexCall() + + for _ in range(_NUM_STREAM_RESPONSES): + await call.write(request) + response = await call.read() + assert _RESPONSE_PAYLOAD_SIZE == len(response.payload.body) + + await call.done_writing() + assert await call.code() == grpc.StatusCode.OK + + # Calling sync API in a different thread + def sync_work() -> None: + response_iterator = self._sync_stub.FullDuplexCall(iter([request])) + for response in response_iterator: + assert _RESPONSE_PAYLOAD_SIZE == len(response.payload.body) + self.assertEqual(grpc.StatusCode.OK, response_iterator.code()) + + await self._run_in_another_thread(sync_work) + + async def test_server(self): + + class GenericHandlers(grpc.GenericRpcHandler): + + def service(self, handler_call_details): + return grpc.unary_unary_rpc_method_handler(lambda x, _: x) + + # It's fine to instantiate server object in the event loop thread. + # The server will spawn its own serving thread. + server = grpc.server(ThreadPoolExecutor(), + handlers=(GenericHandlers(),)) + port = server.add_insecure_port('localhost:0') + server.start() + + def sync_work() -> None: + for _ in range(100): + with grpc.insecure_channel('localhost:%d' % port) as channel: + response = channel.unary_unary('/test/test')(b'\x07\x08') + self.assertEqual(response, b'\x07\x08') + + await self._run_in_another_thread(sync_work) + + async def test_many_loop(self): + address, server = await start_test_server() + + # Run another loop in another thread + def sync_work(): + + async def async_work(): + # Create async stub + async_channel = aio.insecure_channel(address, + options=_unique_options()) + async_stub = test_pb2_grpc.TestServiceStub(async_channel) + + call = async_stub.UnaryCall(messages_pb2.SimpleRequest()) + response = await call + self.assertIsInstance(response, messages_pb2.SimpleResponse) + self.assertEqual(grpc.StatusCode.OK, await call.code()) + + loop = asyncio.new_event_loop() + loop.run_until_complete(async_work()) + + await self._run_in_another_thread(sync_work) + await server.stop(None) + + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/init_test.py b/src/python/grpcio_tests/tests_aio/unit/init_test.py index 8b9a03e2dd3..2582857751d 100644 --- a/src/python/grpcio_tests/tests_aio/unit/init_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/init_test.py @@ -20,8 +20,14 @@ from grpc.experimental import aio from tests_aio.unit._test_server import start_test_server from tests_aio.unit._test_base import AioTestBase +from tests.unit import resources -class TestInsecureChannel(AioTestBase): +_PRIVATE_KEY = resources.private_key() +_CERTIFICATE_CHAIN = resources.certificate_chain() +_TEST_ROOT_CERTIFICATES = resources.test_root_certificates() + + +class TestChannel(AioTestBase): async def test_insecure_channel(self): server_target, _ = await start_test_server() # pylint: disable=unused-variable @@ -29,23 +35,18 @@ class TestInsecureChannel(AioTestBase): channel = aio.insecure_channel(server_target) self.assertIsInstance(channel, aio.Channel) + async def test_secure_channel(self): + server_target, _ = await start_test_server(secure=True) # pylint: disable=unused-variable + credentials = grpc.ssl_channel_credentials( + root_certificates=_TEST_ROOT_CERTIFICATES, + private_key=_PRIVATE_KEY, + certificate_chain=_CERTIFICATE_CHAIN, + ) + secure_channel = aio.secure_channel(server_target, credentials) -class TestSecureChannel(AioTestBase): - """Test a secure channel connected to a secure server""" - - def test_secure_channel(self): - - async def coro(): - server_target, _ = await start_test_server(secure=True) # pylint: disable=unused-variable - credentials = grpc.local_channel_credentials( - grpc.LocalConnectionType.LOCAL_TCP) - secure_channel = aio.secure_channel(server_target, credentials) - - self.assertIsInstance(secure_channel, aio.Channel) - - self.loop.run_until_complete(coro()) + self.assertIsInstance(secure_channel, aio.Channel) if __name__ == '__main__': - logging.basicConfig() + logging.basicConfig(level=logging.DEBUG) unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/secure_call_test.py b/src/python/grpcio_tests/tests_aio/unit/secure_call_test.py new file mode 100644 index 00000000000..7efaddd607e --- /dev/null +++ b/src/python/grpcio_tests/tests_aio/unit/secure_call_test.py @@ -0,0 +1,130 @@ +# Copyright 2020 The 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. +"""Tests the behaviour of the Call classes under a secure channel.""" + +import unittest +import logging + +import grpc +from grpc.experimental import aio +from src.proto.grpc.testing import messages_pb2, test_pb2_grpc +from tests_aio.unit._test_base import AioTestBase +from tests_aio.unit._test_server import start_test_server +from tests.unit import resources + +_SERVER_HOST_OVERRIDE = 'foo.test.google.fr' +_NUM_STREAM_RESPONSES = 5 +_RESPONSE_PAYLOAD_SIZE = 42 + + +class _SecureCallMixin: + """A Mixin to run the call tests over a secure channel.""" + + async def setUp(self): + server_credentials = grpc.ssl_server_credentials([ + (resources.private_key(), resources.certificate_chain()) + ]) + channel_credentials = grpc.ssl_channel_credentials( + resources.test_root_certificates()) + + self._server_address, self._server = await start_test_server( + secure=True, server_credentials=server_credentials) + channel_options = (( + 'grpc.ssl_target_name_override', + _SERVER_HOST_OVERRIDE, + ),) + self._channel = aio.secure_channel(self._server_address, + channel_credentials, channel_options) + self._stub = test_pb2_grpc.TestServiceStub(self._channel) + + async def tearDown(self): + await self._channel.close() + await self._server.stop(None) + + +class TestUnaryUnarySecureCall(_SecureCallMixin, AioTestBase): + """unary_unary Calls made over a secure channel.""" + + async def test_call_ok_over_secure_channel(self): + call = self._stub.UnaryCall(messages_pb2.SimpleRequest()) + response = await call + self.assertIsInstance(response, messages_pb2.SimpleResponse) + self.assertEqual(await call.code(), grpc.StatusCode.OK) + + async def test_call_with_credentials(self): + call_credentials = grpc.composite_call_credentials( + grpc.access_token_call_credentials("abc"), + grpc.access_token_call_credentials("def"), + ) + call = self._stub.UnaryCall(messages_pb2.SimpleRequest(), + credentials=call_credentials) + response = await call + + self.assertIsInstance(response, messages_pb2.SimpleResponse) + + +class TestUnaryStreamSecureCall(_SecureCallMixin, AioTestBase): + """unary_stream calls over a secure channel""" + + async def test_unary_stream_async_generator_secure(self): + request = messages_pb2.StreamingOutputCallRequest() + request.response_parameters.extend( + messages_pb2.ResponseParameters(size=_RESPONSE_PAYLOAD_SIZE,) + for _ in range(_NUM_STREAM_RESPONSES)) + call_credentials = grpc.composite_call_credentials( + grpc.access_token_call_credentials("abc"), + grpc.access_token_call_credentials("def"), + ) + call = self._stub.StreamingOutputCall(request, + credentials=call_credentials) + + async for response in call: + self.assertIsInstance(response, + messages_pb2.StreamingOutputCallResponse) + self.assertEqual(len(response.payload.body), _RESPONSE_PAYLOAD_SIZE) + + self.assertEqual(await call.code(), grpc.StatusCode.OK) + + +# Prepares the request that stream in a ping-pong manner. +_STREAM_OUTPUT_REQUEST_ONE_RESPONSE = messages_pb2.StreamingOutputCallRequest() +_STREAM_OUTPUT_REQUEST_ONE_RESPONSE.response_parameters.append( + messages_pb2.ResponseParameters(size=_RESPONSE_PAYLOAD_SIZE)) + + +class TestStreamStreamSecureCall(_SecureCallMixin, AioTestBase): + _STREAM_ITERATIONS = 2 + + async def test_async_generator_secure_channel(self): + + async def request_generator(): + for _ in range(self._STREAM_ITERATIONS): + yield _STREAM_OUTPUT_REQUEST_ONE_RESPONSE + + call_credentials = grpc.composite_call_credentials( + grpc.access_token_call_credentials("abc"), + grpc.access_token_call_credentials("def"), + ) + + call = self._stub.FullDuplexCall(request_generator(), + credentials=call_credentials) + async for response in call: + self.assertEqual(_RESPONSE_PAYLOAD_SIZE, len(response.payload.body)) + + self.assertEqual(await call.code(), grpc.StatusCode.OK) + + +if __name__ == '__main__': + logging.basicConfig(level=logging.DEBUG) + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_aio/unit/server_interceptor_test.py b/src/python/grpcio_tests/tests_aio/unit/server_interceptor_test.py index 0c443389967..dabf005591f 100644 --- a/src/python/grpcio_tests/tests_aio/unit/server_interceptor_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/server_interceptor_test.py @@ -164,5 +164,5 @@ class TestServerInterceptor(AioTestBase): if __name__ == '__main__': - logging.basicConfig() + logging.basicConfig(level=logging.DEBUG) unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests_py3_only/interop/BUILD.bazel b/src/python/grpcio_tests/tests_py3_only/interop/BUILD.bazel new file mode 100644 index 00000000000..21d207119d0 --- /dev/null +++ b/src/python/grpcio_tests/tests_py3_only/interop/BUILD.bazel @@ -0,0 +1,12 @@ +py_binary( + name = "xds_interop_client", + srcs = ["xds_interop_client.py"], + python_version = "PY3", + deps = [ + "//src/proto/grpc/testing:empty_py_pb2", + "//src/proto/grpc/testing:py_messages_proto", + "//src/proto/grpc/testing:py_test_proto", + "//src/proto/grpc/testing:test_py_pb2_grpc", + "//src/python/grpcio/grpc:grpcio", + ], +) diff --git a/src/python/grpcio_tests/tests_py3_only/interop/xds_interop_client.py b/src/python/grpcio_tests/tests_py3_only/interop/xds_interop_client.py new file mode 100644 index 00000000000..bd13d9aeca6 --- /dev/null +++ b/src/python/grpcio_tests/tests_py3_only/interop/xds_interop_client.py @@ -0,0 +1,254 @@ +# Copyright 2020 The 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. + +import argparse +import logging +import signal +import threading +import time +import sys + +from typing import DefaultDict, Dict, List, Mapping, Set +import collections + +from concurrent import futures + +import grpc + +from src.proto.grpc.testing import test_pb2 +from src.proto.grpc.testing import test_pb2_grpc +from src.proto.grpc.testing import messages_pb2 +from src.proto.grpc.testing import empty_pb2 + +logger = logging.getLogger() +console_handler = logging.StreamHandler() +formatter = logging.Formatter(fmt='%(asctime)s: %(levelname)-8s %(message)s') +console_handler.setFormatter(formatter) +logger.addHandler(console_handler) + + +class _StatsWatcher: + _start: int + _end: int + _rpcs_needed: int + _rpcs_by_peer: DefaultDict[str, int] + _no_remote_peer: int + _lock: threading.Lock + _condition: threading.Condition + + def __init__(self, start: int, end: int): + self._start = start + self._end = end + self._rpcs_needed = end - start + self._rpcs_by_peer = collections.defaultdict(int) + self._condition = threading.Condition() + self._no_remote_peer = 0 + + def on_rpc_complete(self, request_id: int, peer: str) -> None: + """Records statistics for a single RPC.""" + if self._start <= request_id < self._end: + with self._condition: + if not peer: + self._no_remote_peer += 1 + else: + self._rpcs_by_peer[peer] += 1 + self._rpcs_needed -= 1 + self._condition.notify() + + def await_rpc_stats_response(self, timeout_sec: int + ) -> messages_pb2.LoadBalancerStatsResponse: + """Blocks until a full response has been collected.""" + with self._condition: + self._condition.wait_for(lambda: not self._rpcs_needed, + timeout=float(timeout_sec)) + response = messages_pb2.LoadBalancerStatsResponse() + for peer, count in self._rpcs_by_peer.items(): + response.rpcs_by_peer[peer] = count + response.num_failures = self._no_remote_peer + self._rpcs_needed + return response + + +_global_lock = threading.Lock() +_stop_event = threading.Event() +_global_rpc_id: int = 0 +_watchers: Set[_StatsWatcher] = set() +_global_server = None + + +def _handle_sigint(sig, frame): + _stop_event.set() + _global_server.stop(None) + + +class _LoadBalancerStatsServicer(test_pb2_grpc.LoadBalancerStatsServiceServicer + ): + + def __init__(self): + super(_LoadBalancerStatsServicer).__init__() + + def GetClientStats(self, request: messages_pb2.LoadBalancerStatsRequest, + context: grpc.ServicerContext + ) -> messages_pb2.LoadBalancerStatsResponse: + logger.info("Received stats request.") + start = None + end = None + watcher = None + with _global_lock: + start = _global_rpc_id + 1 + end = start + request.num_rpcs + watcher = _StatsWatcher(start, end) + _watchers.add(watcher) + response = watcher.await_rpc_stats_response(request.timeout_sec) + with _global_lock: + _watchers.remove(watcher) + logger.info("Returning stats response: {}".format(response)) + return response + + +def _start_rpc(request_id: int, stub: test_pb2_grpc.TestServiceStub, + timeout: float, futures: Mapping[int, grpc.Future]) -> None: + logger.info(f"Sending request to backend: {request_id}") + future = stub.UnaryCall.future(messages_pb2.SimpleRequest(), + timeout=timeout) + futures[request_id] = future + + +def _on_rpc_done(rpc_id: int, future: grpc.Future, + print_response: bool) -> None: + exception = future.exception() + hostname = "" + if exception is not None: + if exception.code() == grpc.StatusCode.DEADLINE_EXCEEDED: + logger.error(f"RPC {rpc_id} timed out") + else: + logger.error(exception) + else: + response = future.result() + logger.info(f"Got result {rpc_id}") + hostname = response.hostname + if print_response: + if future.code() == grpc.StatusCode.OK: + logger.info("Successful response.") + else: + logger.info(f"RPC failed: {call}") + with _global_lock: + for watcher in _watchers: + watcher.on_rpc_complete(rpc_id, hostname) + + +def _remove_completed_rpcs(futures: Mapping[int, grpc.Future], + print_response: bool) -> None: + logger.debug("Removing completed RPCs") + done = [] + for future_id, future in futures.items(): + if future.done(): + _on_rpc_done(future_id, future, args.print_response) + done.append(future_id) + for rpc_id in done: + del futures[rpc_id] + + +def _cancel_all_rpcs(futures: Mapping[int, grpc.Future]) -> None: + logger.info("Cancelling all remaining RPCs") + for future in futures.values(): + future.cancel() + + +def _run_single_channel(args: argparse.Namespace): + global _global_rpc_id # pylint: disable=global-statement + duration_per_query = 1.0 / float(args.qps) + with grpc.insecure_channel(args.server) as channel: + stub = test_pb2_grpc.TestServiceStub(channel) + futures: Dict[int, grpc.Future] = {} + while not _stop_event.is_set(): + request_id = None + with _global_lock: + request_id = _global_rpc_id + _global_rpc_id += 1 + start = time.time() + end = start + duration_per_query + _start_rpc(request_id, stub, float(args.rpc_timeout_sec), futures) + _remove_completed_rpcs(futures, args.print_response) + logger.debug(f"Currently {len(futures)} in-flight RPCs") + now = time.time() + while now < end: + time.sleep(end - now) + now = time.time() + _cancel_all_rpcs(futures) + + +def _run(args: argparse.Namespace) -> None: + logger.info("Starting python xDS Interop Client.") + global _global_server # pylint: disable=global-statement + channel_threads: List[threading.Thread] = [] + for i in range(args.num_channels): + thread = threading.Thread(target=_run_single_channel, args=(args,)) + thread.start() + channel_threads.append(thread) + _global_server = grpc.server(futures.ThreadPoolExecutor()) + _global_server.add_insecure_port(f"0.0.0.0:{args.stats_port}") + test_pb2_grpc.add_LoadBalancerStatsServiceServicer_to_server( + _LoadBalancerStatsServicer(), _global_server) + _global_server.start() + _global_server.wait_for_termination() + for i in range(args.num_channels): + thread.join() + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description='Run Python XDS interop client.') + parser.add_argument( + "--num_channels", + default=1, + type=int, + help="The number of channels from which to send requests.") + parser.add_argument("--print_response", + default=False, + action="store_true", + help="Write RPC response to STDOUT.") + parser.add_argument( + "--qps", + default=1, + type=int, + help="The number of queries to send from each channel per second.") + parser.add_argument("--rpc_timeout_sec", + default=30, + type=int, + help="The per-RPC timeout in seconds.") + parser.add_argument("--server", + default="localhost:50051", + help="The address of the server.") + parser.add_argument( + "--stats_port", + default=50052, + type=int, + help="The port on which to expose the peer distribution stats service.") + parser.add_argument('--verbose', + help='verbose log output', + default=False, + action='store_true') + parser.add_argument("--log_file", + default=None, + type=str, + help="A file to log to.") + args = parser.parse_args() + signal.signal(signal.SIGINT, _handle_sigint) + if args.verbose: + logger.setLevel(logging.DEBUG) + if args.log_file: + file_handler = logging.FileHandler(args.log_file, mode='a') + file_handler.setFormatter(formatter) + logger.addHandler(file_handler) + _run(args) diff --git a/src/ruby/spec/testdata/ca.pem b/src/ruby/spec/testdata/ca.pem index 6c8511a73c6..49d39cd8ed5 100755 --- a/src/ruby/spec/testdata/ca.pem +++ b/src/ruby/spec/testdata/ca.pem @@ -1,15 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla -Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT -BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 -+L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu -g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd -Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau -sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m -oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG -Dfcog5wrJytaQ6UA0wE= +MIIDWjCCAkKgAwIBAgIUWrP0VvHcy+LP6UuYNtiL9gBhD5owDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxNzE4NTk1MVoXDTMwMDMxNTE4NTk1MVowVjELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDEPMA0GA1UEAwwGdGVzdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAsGL0oXflF0LzoM+Bh+qUU9yhqzw2w8OOX5mu/iNCyUOBrqaHi7mGHx73GD01 +diNzCzvlcQqdNIH6NQSL7DTpBjca66jYT9u73vZe2MDrr1nVbuLvfu9850cdxiUO +Inv5xf8+sTHG0C+a+VAvMhsLiRjsq+lXKRJyk5zkbbsETybqpxoJ+K7CoSy3yc/k +QIY3TipwEtwkKP4hzyo6KiGd/DPexie4nBUInN3bS1BUeNZ5zeaIC2eg3bkeeW7c +qT55b+Yen6CxY0TEkzBK6AKt/WUialKMgT0wbTxRZO7kUCH3Sq6e/wXeFdJ+HvdV +LPlAg5TnMaNpRdQih/8nRFpsdwIDAQABoyAwHjAMBgNVHRMEBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAkTrKZjBrJXHps/HrjNCFPb5a +THuGPCSsepe1wkKdSp1h4HGRpLoCgcLysCJ5hZhRpHkRihhef+rFHEe60UePQO3S +CVTtdJB4CYWpcNyXOdqefrbJW5QNljxgi6Fhvs7JJkBqdXIkWXtFk2eRgOIP2Eo9 +/OHQHlYnwZFrk6sp4wPyR+A95S0toZBcyDVz7u+hOW0pGK3wviOe9lvRgj/H3Pwt +bewb0l+MhRig0/DVHamyVxrDRbqInU1/GTNCwcZkXKYFWSf92U+kIcTth24Q1gcw +eZiLl5FfrWokUNytFElXob0V0a5/kbhiLc3yWmvWqHTpqCALbVyF+rKJo2f5Kw== -----END CERTIFICATE----- diff --git a/src/ruby/spec/testdata/client.key b/src/ruby/spec/testdata/client.key index f48d0735d99..349b40033dd 100644 --- a/src/ruby/spec/testdata/client.key +++ b/src/ruby/spec/testdata/client.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAOxUR9uhvhbeVUIM -s5WbH0px0mehl2+6sZpNjzvE2KimZpHzMJHukVH0Ffkvhs0b8+S5Ut9VNUAqd3IM -JCCAEGtRNoQhM1t9Yr2zAckSvbRacp+FL/Cj9eDmyo00KsVGaeefA4Dh4OW+ZhkT -NKcldXqkSuj1sEf244JZYuqZp6/tAgMBAAECgYEAi2NSVqpZMafE5YYUTcMGe6QS -k2jtpsqYgggI2RnLJ/2tNZwYI5pwP8QVSbnMaiF4gokD5hGdrNDfTnb2v+yIwYEH -0w8+oG7Z81KodsiZSIDJfTGsAZhVNwOz9y0VD8BBZZ1/274Zh52AUKLjZS/ZwIbS -W2ywya855dPnH/wj+0ECQQD9X8D920kByTNHhBG18biAEZ4pxs9f0OAG8333eVcI -w2lJDLsYDZrCB2ocgA3lUdozlzPC7YDYw8reg0tkiRY5AkEA7sdNzOeQsQRn7++5 -0bP9DtT/iON1gbfxRzCfCfXdoOtfQWIzTePWtURt9X/5D9NofI0Rg5W2oGy/MLe5 -/sXHVQJBAIup5XrJDkQywNZyAUU2ecn2bCWBFjwtqd+LBmuMciI9fOKsZtEKZrz/ -U0lkeMRoSwvXE8wmGLjjrAbdfohrXFkCQQDZEx/LtIl6JINJQiswVe0tWr6k+ASP -1WXoTm+HYpoF/XUvv9LccNF1IazFj34hwRQwhx7w/V52Ieb+p0jUMYGxAkEAjDhd -9pBO1fKXWiXzi9ZKfoyTNcUq3eBSVKwPG2nItg5ycXengjT5sgcWDnciIzW7BIVI -JiqOszq9GWESErAatg== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyqYRp+DXVp72N +FbQH8hdhTZLycZXOlJhmMsrJmrjn2p7pI/8mTZ/0FC+SGWBGZV+ELiHrmCX5zfaI +Lr9Iuw7Ghr3Vzoefi8r62rLupVPNi/qdqyjWk2dECHC9Z3+Ag3KzKTyerXWjKcvy +KVmM0ZxE0RXhDW/RoQbqZsU2GKg1B2rhUU8KN0gVmKn0rJHOxzRVSYeYLYp5Yn7K +rtPJcKyo9aVuEr7dGANzpyF6lg/nYBWc+9SGwkoLdFvKvABYJMyrbNhHUQfv0fza +Z0P86dfTENrDxzALrzGnqcx3KTrwJjkZ/aSr1tyD0/tXvukRFiPxWBJhjHQ70GqT +FQY19RbhAgMBAAECggEAIL8JUhL4awyvpWhQ8xPgTSlWwbEn8BE0TacJnCILuhNM +BRdf8LlRk/8PKQwVpVF3TFbYSMI+U6b4hMVssfv3HVQc/083dHq+3XOwUCVlUstR +SAzTE2E5EDMr1stdh0SQhV4Nilfos9s5Uk1Z6IGSztoz1GgOErIc/mGPy/aA/hbr +fRWHvTp35+MbCJSvZuOeevX2iLs0dNzqdk6DiOWIH/BVGirVPtO6ykrkuTj1FWiN +hyZ3MBChShlNH2poNX46ntOc7nEus0qteOgxBK8lummFEtlehCA7hd/8xuvYlP0k +7aN684LCRDajmAGpoZO57NSDYQhAFGZeUZ93SMFucQKBgQDe7GGkzZFEiv91u1q9 +lgMy1h5dZjIZKgQaOarPC6wCQMUdqCf6cSLsAPr4T8EDoWsnY7dSnrTZ6YCIFL1T +idg8M3BQXipICCJkFORS76pKKZ0wMn3/NgkSepsmNct91WHr6okvx4tOaoRCtdzU +g7jt4Mr3sfLCiZtqTQyySdMUEwKBgQDNK+ZFKL0XhkWZP+PGKjWG8LWpPiK3d78/ +wYBFXzSTGlkr6FvRmYtZeNwXWRYLB4UxZ9At4hbJVEdi/2dITOz/sehVDyCAjjs3 +gycsc3UJqiZbcw5XKhI5TWBuWxkKENdbMSayogVbp2aSYoRblH764//t0ACmbfTW +KUQRQPB/uwKBgQC5QjjjfPL8w4cJkGoYpFKELO2PMR7xSrmeEc6hwlFwjeNCgjy3 +JM6g0y++rIj7O2qRkY0IXFxvvF3UuWedxTCu1xC/uYHp2ti506LsScB7YZoAM/YB +4iYn9Tx6xLoYGP0H0iGwU2SyBlNkHT8oXU+SYP5MWtYkVbeS3/VtNWz1gQKBgQCA +6Nk4kN0mH7YxEKRzSOfyzeDF4oV7kuB2FYUbkTL+TirC3K58JiYY5Egc31trOKFm +Jlz1xz0b6DkmKWTiV3r9OPHKJ8P7IeJxAZWmZzCdDuwkv0i+WW+z0zsIe3JjEavN +3zb6O7R0HtziksWoqMeTqZeO+wa9iw6vVKQw1wWEqwKBgFHfahFs0DZ5cUTpGpBt +F/AQG7ukgipB6N6AkB9kDbgCs1FLgd199MQrEncug5hfpq8QerbyMatmA+GXoGMb +7vztKEH85yzp4n02FNL6H7xL4VVILvyZHdolmiORJ4qT2hZnl8pEQ2TYuF4RlHUd +nSwXX+2o0J/nF85fm4AwWKAc -----END PRIVATE KEY----- diff --git a/src/ruby/spec/testdata/client.pem b/src/ruby/spec/testdata/client.pem index e332091019b..8815875f327 100644 --- a/src/ruby/spec/testdata/client.pem +++ b/src/ruby/spec/testdata/client.pem @@ -1,14 +1,20 @@ -----BEGIN CERTIFICATE----- -MIICHzCCAYgCAQEwDQYJKoZIhvcNAQEFBQAwVjELMAkGA1UEBhMCQVUxEzARBgNV -BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 -ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTE0MDcxNzIzNTYwMloXDTI0MDcxNDIzNTYw -MlowWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UEAwwKdGVzdGNsaWVudDCB -nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA7FRH26G+Ft5VQgyzlZsfSnHSZ6GX -b7qxmk2PO8TYqKZmkfMwke6RUfQV+S+GzRvz5LlS31U1QCp3cgwkIIAQa1E2hCEz -W31ivbMByRK9tFpyn4Uv8KP14ObKjTQqxUZp558DgOHg5b5mGRM0pyV1eqRK6PWw -R/bjglli6pmnr+0CAwEAATANBgkqhkiG9w0BAQUFAAOBgQAStSm5PM7ubROiKK6/ -T2FkKlhiTOx+Ryenm3Eio59emq+jXl+1nhPySX5G2PQzSR5vd1dIhwgZSR4Gyttk -tRZ57k/NI1brUW8joiEOMJA/Mr7H7asx7wIRYDE91Fs8GkKWd5LhoPAQj+qdG35C -OO+svdkmqH0KZo320ZUqdl2ooQ== +MIIDNzCCAh8CFGyX00RCepOv/qCJ1oVdTtY92U83MA0GCSqGSIb3DQEBCwUAMFYx +CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl +cm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnRlc3RjYTAeFw0yMDAzMTgw +MTA2MTBaFw0zMDAzMTYwMTA2MTBaMFoxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApT +b21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEzAR +BgNVBAMMCnRlc3RjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCyqYRp+DXVp72NFbQH8hdhTZLycZXOlJhmMsrJmrjn2p7pI/8mTZ/0FC+SGWBG +ZV+ELiHrmCX5zfaILr9Iuw7Ghr3Vzoefi8r62rLupVPNi/qdqyjWk2dECHC9Z3+A +g3KzKTyerXWjKcvyKVmM0ZxE0RXhDW/RoQbqZsU2GKg1B2rhUU8KN0gVmKn0rJHO +xzRVSYeYLYp5Yn7KrtPJcKyo9aVuEr7dGANzpyF6lg/nYBWc+9SGwkoLdFvKvABY +JMyrbNhHUQfv0fzaZ0P86dfTENrDxzALrzGnqcx3KTrwJjkZ/aSr1tyD0/tXvukR +FiPxWBJhjHQ70GqTFQY19RbhAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAFXCewK8 +cWT+zWxXyGFnouFSBzTi0BMBJRrhsiNoiQxkqityJHWFExiQZie+7CA+EabXCQUB ++JwMSWM29j3mSw10DTfmC3rhheQqGxy304BZyUpdpvI2dt3p/mcsE7O+p4sQrSep +gijiDssKAfxTAmUM93N6+Q8yJK5immxlbeYfijoBvmkzyB/B+qNRPsx0n7aFGnfv +oWfkW296iPhWLiwknpC3xB6oK3vRbK4Zj1OaGb0grK7VN8EyhBix2xVF61i4dzCK +kMIpl7CUpw1Mb2z8q3F2bHBS7iF7g1Ccn5VGcO+aJ+6PWydaeqJ6VEBF0Nwv9woe +mL5AluNRLaqjZvE= -----END CERTIFICATE----- diff --git a/src/ruby/spec/testdata/server1.key b/src/ruby/spec/testdata/server1.key index 143a5b87658..086462992cf 100755 --- a/src/ruby/spec/testdata/server1.key +++ b/src/ruby/spec/testdata/server1.key @@ -1,16 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAOHDFScoLCVJpYDD -M4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1BgzkWF+slf -3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd9N8YwbBY -AckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAECgYAn7qGnM2vbjJNBm0VZCkOkTIWm -V10okw7EPJrdL2mkre9NasghNXbE1y5zDshx5Nt3KsazKOxTT8d0Jwh/3KbaN+YY -tTCbKGW0pXDRBhwUHRcuRzScjli8Rih5UOCiZkhefUTcRb6xIhZJuQy71tjaSy0p -dHZRmYyBYO2YEQ8xoQJBAPrJPhMBkzmEYFtyIEqAxQ/o/A6E+E4w8i+KM7nQCK7q -K4JXzyXVAjLfyBZWHGM2uro/fjqPggGD6QH1qXCkI4MCQQDmdKeb2TrKRh5BY1LR -81aJGKcJ2XbcDu6wMZK4oqWbTX2KiYn9GB0woM6nSr/Y6iy1u145YzYxEV/iMwff -DJULAkB8B2MnyzOg0pNFJqBJuH29bKCcHa8gHJzqXhNO5lAlEbMK95p/P2Wi+4Hd -aiEIAF1BF326QJcvYKmwSmrORp85AkAlSNxRJ50OWrfMZnBgzVjDx3xG6KsFQVk2 -ol6VhqL6dFgKUORFUWBvnKSyhjJxurlPEahV6oo6+A+mPhFY8eUvAkAZQyTdupP3 -XEFQKctGz+9+gKkemDp7LBBMEMBXrGTLPhpEfcjv/7KPdnFHYmhYeBTBnuVmTVWe -F98XJ7tIFfJq +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDnE443EknxvxBq +6+hvn/t09hl8hx366EBYvZmVM/NC+7igXRAjiJiA/mIaCvL3MS0Iz5hBLxSGICU+ +WproA3GCIFITIwcf/ETyWj/5xpgZ4AKrLrjQmmX8mhwUajfF3UvwMJrCOVqPp67t +PtP+2kBXaqrXdvnvXR41FsIB8V7zIAuIZB6bHQhiGVlc1sgZYsE2EGG9WMmHtS86 +qkAOTjG2XyjmPTGAwhGDpYkYrpzp99IiDh4/Veai81hn0ssQkbry0XRD/Ig3jcHh +23WiriPNJ0JsbgXUSLKRPZObA9VgOLy2aXoN84IMaeK3yy+cwSYG/99w93fUZJte +MXwz4oYZAgMBAAECggEBAIVn2Ncai+4xbH0OLWckabwgyJ4IM9rDc0LIU368O1kU +koais8qP9dujAWgfoh3sGh/YGgKn96VnsZjKHlyMgF+r4TaDJn3k2rlAOWcurGlj +1qaVlsV4HiEzp7pxiDmHhWvp4672Bb6iBG+bsjCUOEk/n9o9KhZzIBluRhtxCmw5 +nw4Do7z00PTvN81260uPWSc04IrytvZUiAIx/5qxD72bij2xJ8t/I9GI8g4FtoVB +8pB6S/hJX1PZhh9VlU6Yk+TOfOVnbebG4W5138LkB835eqk3Zz0qsbc2euoi8Hxi +y1VGwQEmMQ63jXz4c6g+X55ifvUK9Jpn5E8pq+pMd7ECgYEA93lYq+Cr54K4ey5t +sWMa+ye5RqxjzgXj2Kqr55jb54VWG7wp2iGbg8FMlkQwzTJwebzDyCSatguEZLuB +gRGroRnsUOy9vBvhKPOch9bfKIl6qOgzMJB267fBVWx5ybnRbWN/I7RvMQf3k+9y +biCIVnxDLEEYyx7z85/5qxsXg/MCgYEA7wmWKtCTn032Hy9P8OL49T0X6Z8FlkDC +Rk42ygrc/MUbugq9RGUxcCxoImOG9JXUpEtUe31YDm2j+/nbvrjl6/bP2qWs0V7l +dTJl6dABP51pCw8+l4cWgBBX08Lkeen812AAFNrjmDCjX6rHjWHLJcpS18fnRRkP +V1d/AHWX7MMCgYEA6Gsw2guhp0Zf2GCcaNK5DlQab8OL4Hwrpttzo4kuTlwtqNKp +Q9H4al9qfF4Cr1TFya98+EVYf8yFRM3NLNjZpe3gwYf2EerlJj7VLcahw0KKzoN1 +QBENfwgPLRk5sDkx9VhSmcfl/diLroZdpAwtv3vo4nEoxeuGFbKTGx3Qkf0CgYEA +xyR+dcb05Ygm3w4klHQTowQ10s1H80iaUcZBgQuR1ghEtDbUPZHsoR5t1xCB02ys +DgAwLv1bChIvxvH/L6KM8ovZ2LekBX4AviWxoBxJnfz/EVau98B0b1auRN6eSC83 +FRuGldlSOW1z/nSh8ViizSYE5H5HX1qkXEippvFRE88CgYB3Bfu3YQY60ITWIShv +nNkdcbTT9eoP9suaRJjw92Ln+7ZpALYlQMKUZmJ/5uBmLs4RFwUTQruLOPL4yLTH +awADWUzs3IRr1fwn9E+zM8JVyKCnUEM3w4N5UZskGO2klashAd30hWO+knRv/y0r +uGIYs9Ek7YXlXIRVrzMwcsrt1w== -----END PRIVATE KEY----- diff --git a/src/ruby/spec/testdata/server1.pem b/src/ruby/spec/testdata/server1.pem index f3d43fcc5be..88244f856c6 100755 --- a/src/ruby/spec/testdata/server1.pem +++ b/src/ruby/spec/testdata/server1.pem @@ -1,16 +1,22 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET -MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ -dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx -MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV -BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50 -ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco -LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg -zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd -9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw -CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy -em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G -CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6 -hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh -y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8 +MIIDtDCCApygAwIBAgIUbJfTREJ6k6/+oInWhV1O1j3ZT0IwDQYJKoZIhvcNAQEL +BQAwVjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEPMA0GA1UEAwwGdGVzdGNhMB4XDTIw +MDMxODAzMTA0MloXDTMwMDMxNjAzMTA0MlowZTELMAkGA1UEBhMCVVMxETAPBgNV +BAgMCElsbGlub2lzMRAwDgYDVQQHDAdDaGljYWdvMRUwEwYDVQQKDAxFeGFtcGxl +LCBDby4xGjAYBgNVBAMMESoudGVzdC5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA5xOONxJJ8b8Qauvob5/7dPYZfIcd+uhAWL2ZlTPz +Qvu4oF0QI4iYgP5iGgry9zEtCM+YQS8UhiAlPlqa6ANxgiBSEyMHH/xE8lo/+caY +GeACqy640Jpl/JocFGo3xd1L8DCawjlaj6eu7T7T/tpAV2qq13b5710eNRbCAfFe +8yALiGQemx0IYhlZXNbIGWLBNhBhvVjJh7UvOqpADk4xtl8o5j0xgMIRg6WJGK6c +6ffSIg4eP1XmovNYZ9LLEJG68tF0Q/yIN43B4dt1oq4jzSdCbG4F1EiykT2TmwPV +YDi8tml6DfOCDGnit8svnMEmBv/fcPd31GSbXjF8M+KGGQIDAQABo2swaTAJBgNV +HRMEAjAAMAsGA1UdDwQEAwIF4DBPBgNVHREESDBGghAqLnRlc3QuZ29vZ2xlLmZy +ghh3YXRlcnpvb2kudGVzdC5nb29nbGUuYmWCEioudGVzdC55b3V0dWJlLmNvbYcE +wKgBAzANBgkqhkiG9w0BAQsFAAOCAQEAS8hDQA8PSgipgAml7Q3/djwQ644ghWQv +C2Kb+r30RCY1EyKNhnQnIIh/OUbBZvh0M0iYsy6xqXgfDhCB93AA6j0i5cS8fkhH +Jl4RK0tSkGQ3YNY4NzXwQP/vmUgfkw8VBAZ4Y4GKxppdATjffIW+srbAmdDruIRM +wPeikgOoRrXf0LA1fi4TqxARzeRwenQpayNfGHTvVF9aJkl8HoaMunTAdG5pIVcr +9GKi/gEMpXUJbbVv3U5frX1Wo4CFo+rZWJ/LyCMeb0jciNLxSdMwj/E/ZuExlyeZ +gc9ctPjSMvgSyXEKv6Vwobleeg88V2ZgzenziORoWj4KszG/lbQZvg== -----END CERTIFICATE----- diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 1a5c81f5357..e6fc6c034ab 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -252,7 +252,7 @@ ## Some libraries are shared even with BUILD_SHARED_LIBRARIES=OFF set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) - set(CMAKE_MODULE_PATH "<%text>${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + list(APPEND CMAKE_MODULE_PATH "<%text>${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") if(MSVC) include(cmake/msvc_static_runtime.cmake) diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index 88ddea93436..2383620c8ab 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -87,6 +87,7 @@ grpc_cc_test( external_deps = [ "gtest", ], + flaky = True, # TODO(b/151792070) language = "C++", deps = [ "//:gpr", diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 56a552ea9ca..2dc86f10291 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -64,8 +64,9 @@ static grpc_ares_request* my_dns_lookup_ares_locked( const char* /*dns_server*/, const char* addr, const char* /*default_port*/, grpc_pollset_set* /*interested_parties*/, grpc_closure* on_done, std::unique_ptr* addresses, - bool /*check_grpclb*/, char** /*service_config_json*/, - int /*query_timeout_ms*/, grpc_core::Combiner* /*combiner*/) { + std::unique_ptr* /*balancer_addresses*/, + char** /*service_config_json*/, int /*query_timeout_ms*/, + grpc_core::Combiner* /*combiner*/) { gpr_mu_lock(&g_mu); GPR_ASSERT(0 == strcmp("test", addr)); grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc index 94699bd3b31..14b0d9fe40e 100644 --- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc @@ -42,7 +42,8 @@ static grpc_core::Combiner* g_combiner; static grpc_ares_request* (*g_default_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, bool check_grpclb, + std::unique_ptr* addresses, + std::unique_ptr* balancer_addresses, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner); @@ -93,12 +94,14 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* test_dns_lookup_ares_locked( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* /*interested_parties*/, grpc_closure* on_done, - std::unique_ptr* addresses, bool check_grpclb, + std::unique_ptr* addresses, + std::unique_ptr* balancer_addresses, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner) { grpc_ares_request* result = g_default_dns_lookup_ares_locked( dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, - addresses, check_grpclb, service_config_json, query_timeout_ms, combiner); + addresses, balancer_addresses, service_config_json, query_timeout_ms, + combiner); ++g_resolution_count; static grpc_millis last_resolution_time = 0; grpc_millis now = diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc index 01d82cbdd05..c9b5828d92e 100644 --- a/test/core/client_channel/resolvers/fake_resolver_test.cc +++ b/test/core/client_channel/resolvers/fake_resolver_test.cc @@ -86,29 +86,18 @@ static grpc_core::Resolver::Result create_new_resolver_result() { static size_t test_counter = 0; const size_t num_addresses = 2; char* uri_string; - char* balancer_name; // Create address list. grpc_core::Resolver::Result result; for (size_t i = 0; i < num_addresses; ++i) { gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR, test_counter * num_addresses + i); grpc_uri* uri = grpc_uri_parse(uri_string, true); - gpr_asprintf(&balancer_name, "balancer%" PRIuPTR, - test_counter * num_addresses + i); grpc_resolved_address address; GPR_ASSERT(grpc_parse_uri(uri, &address)); grpc_core::InlinedVector args_to_add; - const bool is_balancer = num_addresses % 2; - if (is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name)); - } - grpc_channel_args* args = grpc_channel_args_copy_and_add( - nullptr, args_to_add.data(), args_to_add.size()); - result.addresses.emplace_back(address.addr, address.len, args); - gpr_free(balancer_name); + result.addresses.emplace_back( + address.addr, address.len, + grpc_channel_args_copy_and_add(nullptr, nullptr, 0)); grpc_uri_destroy(uri); gpr_free(uri_string); } diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index ad874736ffb..d659fbeb51d 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -18,6 +18,8 @@ #include +#include "absl/strings/str_cat.h" + #include #include @@ -127,10 +129,10 @@ class ErrorParser : public ServiceConfig::Parser { static const char* GlobalError() { return "ErrorParser : globalError"; } }; -void VerifyRegexMatch(grpc_error* error, const std::regex& e) { +void VerifyRegexMatch(grpc_error* error, const std::regex& regex) { std::smatch match; - std::string s(grpc_error_string(error)); - EXPECT_TRUE(std::regex_search(s, match, e)); + std::string error_str = grpc_error_string(error); + EXPECT_TRUE(std::regex_search(error_str, match, regex)) << error_str; GRPC_ERROR_UNREF(error); } @@ -139,10 +141,10 @@ class ServiceConfigTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 0); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 1); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 0); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 1); } }; @@ -150,46 +152,128 @@ TEST_F(ServiceConfigTest, ErrorCheck1) { const char* test_json = ""; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string("JSON parse error")); - VerifyRegexMatch(error, e); + std::regex regex(std::string("JSON parse error")); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, BasicTest1) { const char* test_json = "{}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); +} + +TEST_F(ServiceConfigTest, SkipMethodConfigWithNoNameOrEmptyName) { + const char* test_json = + "{\"methodConfig\": [" + " {\"method_param\":1}," + " {\"name\":[], \"method_param\":1}," + " {\"name\":[{\"service\":\"TestServ\"}], \"method_param\":2}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); + const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( + grpc_slice_from_static_string("/TestServ/TestMethod")); + ASSERT_NE(vector_ptr, nullptr); + auto parsed_config = ((*vector_ptr)[1]).get(); + EXPECT_EQ(static_cast(parsed_config)->value(), 2); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNames) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"TestServ\"}]}," + " {\"name\":[{\"service\":\"TestServ\"}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple method configs with same name")); + VerifyRegexMatch(error, regex); } -TEST_F(ServiceConfigTest, ErrorNoNames) { - const char* test_json = "{\"methodConfig\": [{\"blah\":1}]}"; +TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNamesWithNullMethod) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"TestServ\",\"method\":null}]}," + " {\"name\":[{\"service\":\"TestServ\"}]}" + "]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Method Params)(.*)(referenced_errors)" - "(.*)(methodConfig)(.*)(referenced_errors)" - "(.*)(No names specified)")); - VerifyRegexMatch(error, e); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple method configs with same name")); + VerifyRegexMatch(error, regex); } -TEST_F(ServiceConfigTest, ErrorNoNamesWithMultipleMethodConfigs) { +TEST_F(ServiceConfigTest, ErrorDuplicateMethodConfigNamesWithEmptyMethod) { const char* test_json = - "{\"methodConfig\": [{}, {\"name\":[{\"service\":\"TestServ\"}]}]}"; + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"TestServ\",\"method\":\"\"}]}," + " {\"name\":[{\"service\":\"TestServ\"}]}" + "]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Method Params)(.*)(referenced_errors)" - "(.*)(methodConfig)(.*)(referenced_errors)" - "(.*)(No names specified)")); - VerifyRegexMatch(error, e); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple method configs with same name")); + VerifyRegexMatch(error, regex); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigs) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{}]}," + " {\"name\":[{}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple default method configs")); + VerifyRegexMatch(error, regex); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigsWithNullService) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":null}]}," + " {\"name\":[{}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple default method configs")); + VerifyRegexMatch(error, regex); +} + +TEST_F(ServiceConfigTest, ErrorDuplicateDefaultMethodConfigsWithEmptyService) { + const char* test_json = + "{\"methodConfig\": [" + " {\"name\":[{\"service\":\"\"}]}," + " {\"name\":[{}]}" + "]}"; + grpc_error* error = GRPC_ERROR_NONE; + auto svc_cfg = ServiceConfig::Create(test_json, &error); + std::regex regex( + std::string("Service config parsing error.*referenced_errors" + ".*Method Params.*referenced_errors" + ".*methodConfig.*referenced_errors" + ".*multiple default method configs")); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, ValidMethodConfig) { @@ -197,56 +281,52 @@ TEST_F(ServiceConfigTest, ValidMethodConfig) { "{\"methodConfig\": [{\"name\":[{\"service\":\"TestServ\"}]}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - EXPECT_TRUE(error == GRPC_ERROR_NONE); + EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); } TEST_F(ServiceConfigTest, Parser1BasicTest1) { const char* test_json = "{\"global_param\":5}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); - EXPECT_TRUE( - (static_cast(svc_cfg->GetGlobalParsedConfig(0))) - ->value() == 5); - EXPECT_TRUE(svc_cfg->GetMethodParsedConfigVector( - grpc_slice_from_static_string("/TestServ/TestMethod")) == - nullptr); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); + EXPECT_EQ((static_cast(svc_cfg->GetGlobalParsedConfig(0))) + ->value(), + 5); + EXPECT_EQ(svc_cfg->GetMethodParsedConfigVector( + grpc_slice_from_static_string("/TestServ/TestMethod")), + nullptr); } TEST_F(ServiceConfigTest, Parser1BasicTest2) { const char* test_json = "{\"global_param\":1000}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); - EXPECT_TRUE( - (static_cast(svc_cfg->GetGlobalParsedConfig(0))) - ->value() == 1000); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); + EXPECT_EQ((static_cast(svc_cfg->GetGlobalParsedConfig(0))) + ->value(), + 1000); } TEST_F(ServiceConfigTest, Parser1ErrorInvalidType) { const char* test_json = "{\"global_param\":\"5\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)") + - TestParser1::InvalidTypeErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*", + TestParser1::InvalidTypeErrorMessage())); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, Parser1ErrorInvalidValue) { const char* test_json = "{\"global_param\":-5}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)") + - TestParser1::InvalidValueErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*", + TestParser1::InvalidValueErrorMessage())); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, Parser2BasicTest) { @@ -255,12 +335,12 @@ TEST_F(ServiceConfigTest, Parser2BasicTest) { "\"method_param\":5}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = ((*vector_ptr)[1]).get(); - EXPECT_TRUE(static_cast(parsed_config)->value() == 5); + EXPECT_EQ(static_cast(parsed_config)->value(), 5); } TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { @@ -269,14 +349,12 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidType) { "\"method_param\":\"5\"}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(" - ".*)(referenced_errors)(.*)") + - TestParser2::InvalidTypeErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors\":\\[.*" + "Method Params.*referenced_errors.*methodConfig.*" + "referenced_errors.*", + TestParser2::InvalidTypeErrorMessage())); + VerifyRegexMatch(error, regex); } TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { @@ -285,14 +363,12 @@ TEST_F(ServiceConfigTest, Parser2ErrorInvalidValue) { "\"method_param\":-5}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Method " - "Params)(.*)(referenced_errors)()(.*)(methodConfig)(" - ".*)(referenced_errors)(.*)") + - TestParser2::InvalidValueErrorMessage()); - VerifyRegexMatch(error, e); + std::regex regex( + absl::StrCat("Service config parsing error.*referenced_errors\":\\[.*" + "Method Params.*referenced_errors.*methodConfig.*" + "referenced_errors.*", + TestParser2::InvalidValueErrorMessage())); + VerifyRegexMatch(error, regex); } // Test parsing with ErrorParsers which always add errors @@ -301,10 +377,10 @@ class ErroredParsersScopingTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 0); - EXPECT_TRUE( - ServiceConfig::RegisterParser(absl::make_unique()) == 1); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 0); + EXPECT_EQ(ServiceConfig::RegisterParser(absl::make_unique()), + 1); } }; @@ -312,33 +388,24 @@ TEST_F(ErroredParsersScopingTest, GlobalParams) { const char* test_json = "{}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + - ErrorParser::GlobalError() + std::string("(.*)") + - ErrorParser::GlobalError()); - VerifyRegexMatch(error, e); + std::regex regex(absl::StrCat( + "Service config parsing error.*referenced_errors\":\\[.*" + "Global Params.*referenced_errors.*", + ErrorParser::GlobalError(), ".*", ErrorParser::GlobalError())); + VerifyRegexMatch(error, regex); } TEST_F(ErroredParsersScopingTest, MethodParams) { const char* test_json = "{\"methodConfig\": [{}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - std::regex e(std::string("(Service config parsing " - "error)(.*)(referenced_errors\":\\[)(.*)(Global " - "Params)(.*)(referenced_errors)()(.*)") + - ErrorParser::GlobalError() + std::string("(.*)") + - ErrorParser::GlobalError() + - std::string("(.*)(Method Params)(.*)(referenced_errors)" - "(.*)(methodConfig)(.*)(referenced_errors)(.*)") + - ErrorParser::MethodError() + std::string("(.*)") + - ErrorParser::MethodError() + - std::string("(.*)(No names specified)")); - VerifyRegexMatch(error, e); + std::regex regex(absl::StrCat( + "Service config parsing error.*referenced_errors\":\\[.*" + "Global Params.*referenced_errors.*", + ErrorParser::GlobalError(), ".*", ErrorParser::GlobalError(), + ".*Method Params.*referenced_errors.*methodConfig.*referenced_errors.*", + ErrorParser::MethodError(), ".*", ErrorParser::MethodError())); + VerifyRegexMatch(error, regex); } class ClientChannelParserTest : public ::testing::Test { @@ -346,9 +413,9 @@ class ClientChannelParserTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE( + EXPECT_EQ( ServiceConfig::RegisterParser( - absl::make_unique()) == + absl::make_unique()), 0); } }; @@ -357,12 +424,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigPickFirst) { const char* test_json = "{\"loadBalancingConfig\": [{\"pick_first\":{}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "pick_first") == 0); + EXPECT_STREQ(lb_config->name(), "pick_first"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { @@ -370,12 +437,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigRoundRobin) { "{\"loadBalancingConfig\": [{\"round_robin\":{}}, {}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); auto parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "round_robin") == 0); + EXPECT_STREQ(lb_config->name(), "round_robin"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { @@ -384,12 +451,12 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigGrpclb) { "[{\"grpclb\":{\"childPolicy\":[{\"pick_first\":{}}]}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "grpclb") == 0); + EXPECT_STREQ(lb_config->name(), "grpclb"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { @@ -402,105 +469,91 @@ TEST_F(ClientChannelParserTest, ValidLoadBalancingConfigXds) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); auto lb_config = parsed_config->parsed_lb_config(); - EXPECT_TRUE(strcmp(lb_config->name(), "xds_experimental") == 0); + EXPECT_STREQ(lb_config->name(), "xds_experimental"); } TEST_F(ClientChannelParserTest, UnknownLoadBalancingConfig) { const char* test_json = "{\"loadBalancingConfig\": [{\"unknown\":{}}]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Global Params)(.*)(referenced_errors)" - "(.*)(Client channel global parser)(.*)(referenced_errors)" - "(.*)(field:loadBalancingConfig)(.*)(referenced_errors)" - "(.*)(No known policy)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingConfig.*referenced_errors.*" + "No known policy"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidGrpclbLoadBalancingConfig) { const char* test_json = - "{\"loadBalancingConfig\": " - "[{\"grpclb\":{\"childPolicy\":[{\"unknown\":{}}]}}]}"; + "{\"loadBalancingConfig\": [" + " {\"grpclb\":{\"childPolicy\":1}}," + " {\"round_robin\":{}}" + "]}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing error)(.*)(referenced_errors)" - "(.*)(Global Params)(.*)(referenced_errors)" - "(.*)(Client channel global parser)(.*)(referenced_errors)" - "(.*)(field:loadBalancingConfig)(.*)(referenced_errors)" - "(.*)(GrpcLb Parser)(.*)(referenced_errors)" - "(.*)(field:childPolicy)(.*)(referenced_errors)" - "(.*)(No known policy)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingConfig.*referenced_errors.*" + "GrpcLb Parser.*referenced_errors.*" + "field:childPolicy.*referenced_errors.*" + "type should be array"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { const char* test_json = "{\"loadBalancingPolicy\":\"pick_first\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); - const auto* lb_policy = parsed_config->parsed_deprecated_lb_policy(); - ASSERT_TRUE(lb_policy != nullptr); - EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); + EXPECT_EQ(parsed_config->parsed_deprecated_lb_policy(), "pick_first"); } TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicyAllCaps) { const char* test_json = "{\"loadBalancingPolicy\":\"PICK_FIRST\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); - const auto* lb_policy = parsed_config->parsed_deprecated_lb_policy(); - ASSERT_TRUE(lb_policy != nullptr); - EXPECT_TRUE(strcmp(lb_policy, "pick_first") == 0); + EXPECT_EQ(parsed_config->parsed_deprecated_lb_policy(), "pick_first"); } TEST_F(ClientChannelParserTest, UnknownLoadBalancingPolicy) { const char* test_json = "{\"loadBalancingPolicy\":\"unknown\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:" - "loadBalancingPolicy error:Unknown lb policy)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingPolicy error:Unknown lb policy"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) { const char* test_json = "{\"loadBalancingPolicy\":\"xds_experimental\"}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:" - "loadBalancingPolicy error:xds_experimental requires a " - "config. Please use loadBalancingConfig instead.)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:loadBalancingPolicy error:xds_experimental requires " + "a config. Please use loadBalancingConfig instead."); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidRetryThrottling) { @@ -513,8 +566,7 @@ TEST_F(ClientChannelParserTest, ValidRetryThrottling) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); @@ -532,16 +584,13 @@ TEST_F(ClientChannelParserTest, RetryThrottlingMissingFields) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " - "field:maxTokens error:Not found)(.*)(field:retryThrottling " - "field:tokenRatio error:Not found)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:retryThrottling field:maxTokens error:Not found.*" + "field:retryThrottling field:tokenRatio error:Not found"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { @@ -554,15 +603,13 @@ TEST_F(ClientChannelParserTest, InvalidRetryThrottlingNegativeMaxTokens) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " - "field:maxTokens error:should be greater than zero)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:retryThrottling field:maxTokens error:should " + "be greater than zero"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { @@ -575,15 +622,13 @@ TEST_F(ClientChannelParserTest, InvalidRetryThrottlingInvalidTokenRatio) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(field:retryThrottling " - "field:tokenRatio error:Failed parsing)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Global Params.*referenced_errors.*" + "Client channel global parser.*referenced_errors.*" + "field:retryThrottling field:tokenRatio " + "error:Failed parsing"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidTimeout) { @@ -598,10 +643,10 @@ TEST_F(ClientChannelParserTest, ValidTimeout) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = ((*vector_ptr)[0]).get(); EXPECT_EQ((static_cast( parsed_config)) @@ -621,16 +666,13 @@ TEST_F(ClientChannelParserTest, InvalidTimeout) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(field:timeout " - "error:Failed parsing)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "field:timeout error:Failed parsing"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidWaitForReady) { @@ -645,12 +687,12 @@ TEST_F(ClientChannelParserTest, ValidWaitForReady) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = ((*vector_ptr)[0]).get(); - EXPECT_TRUE( + ASSERT_TRUE( (static_cast( parsed_config)) ->wait_for_ready() @@ -674,16 +716,13 @@ TEST_F(ClientChannelParserTest, InvalidWaitForReady) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(field:waitForReady " - "error:Type should be true/false)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "field:waitForReady error:Type should be true/false"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidRetryPolicy) { @@ -704,15 +743,14 @@ TEST_F(ClientChannelParserTest, ValidRetryPolicy) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); const auto* parsed_config = static_cast( ((*vector_ptr)[0]).get()); - EXPECT_TRUE(parsed_config->retry_policy() != nullptr); + ASSERT_NE(parsed_config->retry_policy(), nullptr); EXPECT_EQ(parsed_config->retry_policy()->max_attempts, 3); EXPECT_EQ(parsed_config->retry_policy()->initial_backoff, 1000); EXPECT_EQ(parsed_config->retry_policy()->max_backoff, 120000); @@ -739,16 +777,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxAttempts) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:maxAttempts error:should be at least 2)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:maxAttempts error:should be at least 2"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { @@ -769,16 +805,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyInitialBackoff) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:initialBackoff error:Failed to parse)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:initialBackoff error:Failed to parse"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { @@ -799,16 +833,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyMaxBackoff) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:maxBackoff error:failed to parse)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:maxBackoff error:failed to parse"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { @@ -829,16 +861,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:backoffMultiplier error:should be of type number)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:backoffMultiplier error:should be of type number"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { @@ -859,16 +889,14 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e(std::string( - "(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(referenced_errors)(" - ".*)(Client channel " - "parser)(.*)(referenced_errors)(.*)(retryPolicy)(.*)(referenced_errors)(." - "*)(field:retryableStatusCodes error:should be non-empty)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Client channel parser.*referenced_errors.*" + "retryPolicy.*referenced_errors.*" + "field:retryableStatusCodes error:should be non-empty"); + VerifyRegexMatch(error, regex); } TEST_F(ClientChannelParserTest, ValidHealthCheck) { @@ -880,14 +908,13 @@ TEST_F(ClientChannelParserTest, ValidHealthCheck) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* parsed_config = static_cast( svc_cfg->GetGlobalParsedConfig(0)); - ASSERT_TRUE(parsed_config != nullptr); - EXPECT_EQ(strcmp(parsed_config->health_check_service_name(), - "health_check_service_name"), - 0); + ASSERT_NE(parsed_config, nullptr); + EXPECT_STREQ(parsed_config->health_check_service_name(), + "health_check_service_name"); } TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) { @@ -902,12 +929,10 @@ TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(JSON parsing failed)(.*)(referenced_errors)" - "(.*)(duplicate key \"healthCheckConfig\" at index 104)")); - VerifyRegexMatch(error, e); + std::regex regex( + "JSON parsing failed.*referenced_errors.*" + "duplicate key \"healthCheckConfig\" at index 104"); + VerifyRegexMatch(error, regex); } class MessageSizeParserTest : public ::testing::Test { @@ -915,8 +940,9 @@ class MessageSizeParserTest : public ::testing::Test { void SetUp() override { ServiceConfig::Shutdown(); ServiceConfig::Init(); - EXPECT_TRUE(ServiceConfig::RegisterParser( - absl::make_unique()) == 0); + EXPECT_EQ( + ServiceConfig::RegisterParser(absl::make_unique()), + 0); } }; @@ -933,14 +959,13 @@ TEST_F(MessageSizeParserTest, Valid) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error == GRPC_ERROR_NONE); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); const auto* vector_ptr = svc_cfg->GetMethodParsedConfigVector( grpc_slice_from_static_string("/TestServ/TestMethod")); - EXPECT_TRUE(vector_ptr != nullptr); + ASSERT_NE(vector_ptr, nullptr); auto parsed_config = static_cast(((*vector_ptr)[0]).get()); - ASSERT_TRUE(parsed_config != nullptr); + ASSERT_NE(parsed_config, nullptr); EXPECT_EQ(parsed_config->limits().max_send_size, 1024); EXPECT_EQ(parsed_config->limits().max_recv_size, 1024); } @@ -957,16 +982,13 @@ TEST_F(MessageSizeParserTest, InvalidMaxRequestMessageBytes) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Message size " - "parser)(.*)(referenced_errors)(.*)(field:" - "maxRequestMessageBytes error:should be non-negative)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Message size parser.*referenced_errors.*" + "field:maxRequestMessageBytes error:should be non-negative"); + VerifyRegexMatch(error, regex); } TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { @@ -981,16 +1003,14 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) { "}"; grpc_error* error = GRPC_ERROR_NONE; auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Method " - "Params)(.*)(referenced_errors)(.*)(methodConfig)(.*)(" - "referenced_errors)(.*)(Message size " - "parser)(.*)(referenced_errors)(.*)(field:" - "maxResponseMessageBytes error:should be of type number)")); - VerifyRegexMatch(error, e); + std::regex regex( + "Service config parsing error.*referenced_errors.*" + "Method Params.*referenced_errors.*" + "methodConfig.*referenced_errors.*" + "Message size parser.*referenced_errors.*" + "field:maxResponseMessageBytes error:should be of type " + "number"); + VerifyRegexMatch(error, regex); } } // namespace testing diff --git a/test/core/end2end/data/client_certs.cc b/test/core/end2end/data/client_certs.cc index 46fc13927c4..8d9cb9129b9 100644 --- a/test/core/end2end/data/client_certs.cc +++ b/test/core/end2end/data/client_certs.cc @@ -19,310 +19,504 @@ extern const char test_self_signed_client_cert[] = { 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x6f, 0x44, 0x43, 0x43, - 0x41, 0x67, 0x6d, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4a, - 0x41, 0x4e, 0x49, 0x7a, 0x32, 0x2f, 0x7a, 0x6f, 0x52, 0x69, 0x61, 0x70, - 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, - 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4d, 0x47, 0x6b, 0x78, - 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x59, - 0x54, 0x41, 0x6b, 0x46, 0x56, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51, 0x59, - 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x70, 0x54, 0x62, 0x32, 0x31, - 0x6c, 0x4c, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x53, 0x45, - 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x68, - 0x4a, 0x62, 0x6e, 0x52, 0x6c, 0x63, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42, - 0x58, 0x0a, 0x61, 0x57, 0x52, 0x6e, 0x61, 0x58, 0x52, 0x7a, 0x49, 0x46, - 0x42, 0x30, 0x65, 0x53, 0x42, 0x4d, 0x64, 0x47, 0x51, 0x78, 0x49, 0x6a, - 0x41, 0x67, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x47, 0x57, - 0x4a, 0x68, 0x5a, 0x47, 0x4e, 0x73, 0x61, 0x57, 0x56, 0x75, 0x64, 0x43, - 0x35, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64, 0x76, 0x62, 0x32, - 0x64, 0x73, 0x5a, 0x53, 0x35, 0x6a, 0x0a, 0x62, 0x32, 0x30, 0x77, 0x48, - 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x51, 0x77, 0x4e, 0x7a, 0x49, 0x34, 0x4d, - 0x6a, 0x41, 0x77, 0x4f, 0x44, 0x49, 0x31, 0x57, 0x68, 0x63, 0x4e, 0x4d, - 0x6a, 0x51, 0x77, 0x4e, 0x7a, 0x49, 0x31, 0x4d, 0x6a, 0x41, 0x77, 0x4f, - 0x44, 0x49, 0x31, 0x57, 0x6a, 0x42, 0x70, 0x4d, 0x51, 0x73, 0x77, 0x43, - 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x42, 0x0a, - 0x56, 0x54, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, - 0x43, 0x41, 0x77, 0x4b, 0x55, 0x32, 0x39, 0x74, 0x5a, 0x53, 0x31, 0x54, - 0x64, 0x47, 0x46, 0x30, 0x5a, 0x54, 0x45, 0x68, 0x4d, 0x42, 0x38, 0x47, - 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x59, 0x53, 0x57, 0x35, 0x30, - 0x5a, 0x58, 0x4a, 0x75, 0x5a, 0x58, 0x51, 0x67, 0x56, 0x32, 0x6c, 0x6b, - 0x5a, 0x32, 0x6c, 0x30, 0x0a, 0x63, 0x79, 0x42, 0x51, 0x64, 0x48, 0x6b, - 0x67, 0x54, 0x48, 0x52, 0x6b, 0x4d, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, - 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x42, 0x6c, 0x69, 0x59, 0x57, 0x52, - 0x6a, 0x62, 0x47, 0x6c, 0x6c, 0x62, 0x6e, 0x51, 0x75, 0x64, 0x47, 0x56, - 0x7a, 0x64, 0x43, 0x35, 0x6e, 0x62, 0x32, 0x39, 0x6e, 0x62, 0x47, 0x55, - 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x49, 0x47, 0x66, 0x0a, 0x4d, 0x41, - 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, - 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x47, 0x4e, 0x41, 0x44, - 0x43, 0x42, 0x69, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x43, 0x79, 0x58, 0x32, - 0x4a, 0x78, 0x5a, 0x2b, 0x4a, 0x35, 0x49, 0x2b, 0x64, 0x6c, 0x68, 0x52, - 0x4f, 0x56, 0x74, 0x71, 0x6c, 0x4d, 0x51, 0x6e, 0x34, 0x37, 0x42, 0x42, - 0x63, 0x72, 0x0a, 0x6c, 0x32, 0x47, 0x43, 0x6b, 0x76, 0x39, 0x4f, 0x31, - 0x44, 0x31, 0x72, 0x4c, 0x39, 0x34, 0x4b, 0x57, 0x59, 0x62, 0x59, 0x31, - 0x34, 0x48, 0x58, 0x68, 0x69, 0x2f, 0x6e, 0x61, 0x63, 0x42, 0x41, 0x51, - 0x74, 0x43, 0x45, 0x51, 0x77, 0x58, 0x78, 0x70, 0x35, 0x44, 0x4b, 0x65, - 0x6d, 0x47, 0x4f, 0x55, 0x6a, 0x75, 0x36, 0x35, 0x78, 0x4d, 0x39, 0x46, - 0x39, 0x36, 0x2f, 0x33, 0x37, 0x34, 0x47, 0x0a, 0x4d, 0x76, 0x6e, 0x52, - 0x4a, 0x64, 0x6f, 0x35, 0x32, 0x67, 0x4f, 0x73, 0x34, 0x48, 0x4f, 0x30, - 0x63, 0x7a, 0x42, 0x70, 0x66, 0x56, 0x4e, 0x64, 0x58, 0x65, 0x65, 0x6f, - 0x44, 0x2f, 0x52, 0x59, 0x67, 0x77, 0x74, 0x74, 0x66, 0x64, 0x4a, 0x72, - 0x7a, 0x2f, 0x34, 0x61, 0x61, 0x74, 0x73, 0x53, 0x32, 0x51, 0x6b, 0x32, - 0x79, 0x4d, 0x59, 0x70, 0x71, 0x5a, 0x6d, 0x71, 0x45, 0x4d, 0x73, 0x62, - 0x0a, 0x72, 0x68, 0x39, 0x57, 0x32, 0x32, 0x4c, 0x70, 0x33, 0x72, 0x43, - 0x42, 0x76, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x31, 0x41, - 0x77, 0x54, 0x6a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x34, - 0x45, 0x46, 0x67, 0x51, 0x55, 0x35, 0x32, 0x33, 0x41, 0x4a, 0x4d, 0x52, - 0x38, 0x44, 0x73, 0x39, 0x56, 0x38, 0x66, 0x68, 0x66, 0x37, 0x67, 0x75, - 0x31, 0x69, 0x30, 0x4d, 0x4d, 0x0a, 0x55, 0x71, 0x41, 0x77, 0x48, 0x77, - 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, - 0x41, 0x55, 0x35, 0x32, 0x33, 0x41, 0x4a, 0x4d, 0x52, 0x38, 0x44, 0x73, - 0x39, 0x56, 0x38, 0x66, 0x68, 0x66, 0x37, 0x67, 0x75, 0x31, 0x69, 0x30, - 0x4d, 0x4d, 0x55, 0x71, 0x41, 0x77, 0x44, 0x41, 0x59, 0x44, 0x56, 0x52, - 0x30, 0x54, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x0a, 0x2f, - 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, - 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x41, 0x4f, 0x42, 0x67, - 0x51, 0x43, 0x49, 0x2f, 0x74, 0x76, 0x53, 0x42, 0x59, 0x48, 0x31, 0x69, - 0x79, 0x66, 0x4c, 0x61, 0x43, 0x54, 0x42, 0x4b, 0x77, 0x70, 0x64, 0x6a, - 0x33, 0x36, 0x2b, 0x4d, 0x6b, 0x52, 0x39, 0x45, 0x65, 0x4a, 0x4a, 0x6d, - 0x49, 0x6d, 0x78, 0x0a, 0x58, 0x2b, 0x62, 0x6a, 0x68, 0x4b, 0x57, 0x58, - 0x77, 0x73, 0x42, 0x58, 0x34, 0x50, 0x44, 0x4d, 0x57, 0x76, 0x64, 0x75, - 0x73, 0x72, 0x2b, 0x2b, 0x51, 0x47, 0x55, 0x59, 0x74, 0x79, 0x6f, 0x79, - 0x61, 0x2b, 0x68, 0x66, 0x59, 0x4d, 0x58, 0x52, 0x68, 0x58, 0x75, 0x61, - 0x33, 0x39, 0x6d, 0x44, 0x35, 0x34, 0x78, 0x67, 0x6c, 0x6f, 0x51, 0x4e, - 0x75, 0x75, 0x39, 0x52, 0x45, 0x44, 0x77, 0x58, 0x0a, 0x46, 0x66, 0x74, - 0x6f, 0x2b, 0x61, 0x4f, 0x77, 0x33, 0x42, 0x63, 0x59, 0x64, 0x75, 0x63, - 0x7a, 0x36, 0x6f, 0x66, 0x78, 0x69, 0x63, 0x46, 0x4b, 0x2f, 0x59, 0x32, - 0x56, 0x65, 0x58, 0x44, 0x75, 0x72, 0x53, 0x4d, 0x70, 0x52, 0x76, 0x35, - 0x54, 0x66, 0x47, 0x66, 0x32, 0x51, 0x72, 0x36, 0x65, 0x4f, 0x4f, 0x64, - 0x61, 0x52, 0x68, 0x6a, 0x36, 0x65, 0x64, 0x37, 0x42, 0x69, 0x62, 0x48, - 0x6b, 0x0a, 0x58, 0x31, 0x56, 0x47, 0x5a, 0x41, 0x3d, 0x3d, 0x0a, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, - 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x0a, 0x00}; + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x73, 0x7a, 0x43, 0x43, + 0x41, 0x70, 0x75, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, + 0x4f, 0x4e, 0x57, 0x62, 0x6b, 0x55, 0x6e, 0x31, 0x6f, 0x62, 0x48, 0x43, + 0x77, 0x39, 0x4c, 0x37, 0x6c, 0x4d, 0x4e, 0x45, 0x45, 0x35, 0x52, 0x45, + 0x76, 0x62, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, + 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41, + 0x77, 0x61, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, + 0x45, 0x42, 0x68, 0x4d, 0x43, 0x51, 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, + 0x52, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, + 0x76, 0x62, 0x57, 0x55, 0x74, 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, + 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, + 0x4d, 0x0a, 0x47, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, + 0x56, 0x30, 0x49, 0x46, 0x64, 0x70, 0x5a, 0x47, 0x64, 0x70, 0x64, 0x48, + 0x4d, 0x67, 0x55, 0x48, 0x52, 0x35, 0x49, 0x45, 0x78, 0x30, 0x5a, 0x44, + 0x45, 0x69, 0x4d, 0x43, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, + 0x77, 0x5a, 0x59, 0x6d, 0x46, 0x6b, 0x59, 0x32, 0x78, 0x70, 0x5a, 0x57, + 0x35, 0x30, 0x4c, 0x6e, 0x52, 0x6c, 0x0a, 0x63, 0x33, 0x51, 0x75, 0x5a, + 0x32, 0x39, 0x76, 0x5a, 0x32, 0x78, 0x6c, 0x4c, 0x6d, 0x4e, 0x76, 0x62, + 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4d, 0x44, 0x41, 0x7a, 0x4d, + 0x54, 0x63, 0x78, 0x4e, 0x7a, 0x51, 0x7a, 0x4d, 0x6a, 0x4e, 0x61, 0x46, + 0x77, 0x30, 0x7a, 0x4d, 0x44, 0x41, 0x7a, 0x4d, 0x54, 0x55, 0x78, 0x4e, + 0x7a, 0x51, 0x7a, 0x4d, 0x6a, 0x4e, 0x61, 0x4d, 0x47, 0x6b, 0x78, 0x0a, + 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, + 0x41, 0x6b, 0x46, 0x56, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51, 0x59, 0x44, + 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x70, 0x54, 0x62, 0x32, 0x31, 0x6c, + 0x4c, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x53, 0x45, 0x77, + 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x68, 0x4a, + 0x62, 0x6e, 0x52, 0x6c, 0x0a, 0x63, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42, + 0x58, 0x61, 0x57, 0x52, 0x6e, 0x61, 0x58, 0x52, 0x7a, 0x49, 0x46, 0x42, + 0x30, 0x65, 0x53, 0x42, 0x4d, 0x64, 0x47, 0x51, 0x78, 0x49, 0x6a, 0x41, + 0x67, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x47, 0x57, 0x4a, + 0x68, 0x5a, 0x47, 0x4e, 0x73, 0x61, 0x57, 0x56, 0x75, 0x64, 0x43, 0x35, + 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64, 0x76, 0x0a, 0x62, 0x32, + 0x64, 0x73, 0x5a, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x30, 0x77, 0x67, 0x67, + 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, + 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, + 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, + 0x49, 0x42, 0x41, 0x51, 0x44, 0x76, 0x64, 0x7a, 0x4b, 0x44, 0x54, 0x59, + 0x76, 0x52, 0x0a, 0x67, 0x6a, 0x42, 0x4f, 0x55, 0x4f, 0x72, 0x7a, 0x44, + 0x77, 0x6b, 0x41, 0x5a, 0x47, 0x77, 0x4e, 0x46, 0x48, 0x48, 0x6c, 0x4d, + 0x59, 0x79, 0x4d, 0x47, 0x49, 0x35, 0x74, 0x49, 0x74, 0x6a, 0x33, 0x74, + 0x43, 0x7a, 0x58, 0x6b, 0x62, 0x70, 0x4d, 0x30, 0x75, 0x7a, 0x33, 0x5a, + 0x6a, 0x48, 0x56, 0x61, 0x68, 0x75, 0x2b, 0x65, 0x59, 0x63, 0x2b, 0x4b, + 0x76, 0x59, 0x41, 0x70, 0x4d, 0x36, 0x34, 0x0a, 0x46, 0x32, 0x64, 0x42, + 0x62, 0x31, 0x36, 0x68, 0x73, 0x37, 0x31, 0x33, 0x46, 0x43, 0x6b, 0x38, + 0x6d, 0x69, 0x68, 0x59, 0x41, 0x42, 0x6a, 0x6e, 0x53, 0x6e, 0x64, 0x72, + 0x51, 0x73, 0x6c, 0x2f, 0x55, 0x32, 0x76, 0x38, 0x59, 0x46, 0x54, 0x37, + 0x44, 0x69, 0x70, 0x66, 0x4c, 0x52, 0x65, 0x71, 0x71, 0x61, 0x4f, 0x47, + 0x75, 0x32, 0x6f, 0x39, 0x48, 0x64, 0x76, 0x57, 0x66, 0x69, 0x55, 0x6c, + 0x0a, 0x61, 0x69, 0x43, 0x2f, 0x55, 0x47, 0x47, 0x66, 0x52, 0x2b, 0x59, + 0x62, 0x6c, 0x70, 0x4b, 0x37, 0x43, 0x47, 0x2b, 0x37, 0x2f, 0x68, 0x76, + 0x54, 0x58, 0x74, 0x55, 0x73, 0x4d, 0x77, 0x2b, 0x4f, 0x70, 0x70, 0x6f, + 0x65, 0x48, 0x39, 0x7a, 0x38, 0x37, 0x72, 0x68, 0x4f, 0x4a, 0x4d, 0x78, + 0x74, 0x69, 0x43, 0x37, 0x58, 0x77, 0x55, 0x35, 0x72, 0x68, 0x45, 0x6d, + 0x61, 0x62, 0x2f, 0x31, 0x66, 0x0a, 0x31, 0x58, 0x4d, 0x2f, 0x6e, 0x4c, + 0x6f, 0x5a, 0x72, 0x66, 0x44, 0x41, 0x63, 0x54, 0x62, 0x44, 0x79, 0x77, + 0x6f, 0x65, 0x75, 0x38, 0x32, 0x36, 0x53, 0x4a, 0x33, 0x6d, 0x69, 0x66, + 0x61, 0x6a, 0x71, 0x37, 0x6f, 0x4b, 0x33, 0x4c, 0x44, 0x64, 0x4e, 0x4c, + 0x6a, 0x57, 0x5a, 0x77, 0x66, 0x45, 0x73, 0x43, 0x4f, 0x31, 0x71, 0x70, + 0x32, 0x43, 0x34, 0x67, 0x4c, 0x76, 0x42, 0x6c, 0x4f, 0x4f, 0x0a, 0x4b, + 0x73, 0x57, 0x4f, 0x4c, 0x4e, 0x62, 0x79, 0x36, 0x42, 0x79, 0x78, 0x43, + 0x4f, 0x50, 0x6c, 0x43, 0x54, 0x61, 0x30, 0x55, 0x43, 0x61, 0x56, 0x75, + 0x6f, 0x4e, 0x63, 0x6c, 0x59, 0x6f, 0x6c, 0x37, 0x31, 0x6a, 0x79, 0x69, + 0x31, 0x37, 0x4b, 0x57, 0x2b, 0x4e, 0x6b, 0x30, 0x6e, 0x4e, 0x65, 0x39, + 0x79, 0x61, 0x56, 0x63, 0x79, 0x72, 0x36, 0x48, 0x30, 0x7a, 0x33, 0x62, + 0x49, 0x6d, 0x66, 0x0a, 0x4a, 0x68, 0x62, 0x53, 0x75, 0x34, 0x72, 0x7a, + 0x49, 0x39, 0x33, 0x6e, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, + 0x55, 0x7a, 0x42, 0x52, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, + 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x54, 0x4b, 0x4a, 0x73, 0x6b, 0x45, + 0x59, 0x64, 0x32, 0x6e, 0x64, 0x72, 0x77, 0x69, 0x68, 0x50, 0x54, 0x67, + 0x32, 0x50, 0x7a, 0x59, 0x46, 0x2f, 0x6b, 0x50, 0x0a, 0x67, 0x7a, 0x41, + 0x66, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, + 0x57, 0x67, 0x42, 0x54, 0x4b, 0x4a, 0x73, 0x6b, 0x45, 0x59, 0x64, 0x32, + 0x6e, 0x64, 0x72, 0x77, 0x69, 0x68, 0x50, 0x54, 0x67, 0x32, 0x50, 0x7a, + 0x59, 0x46, 0x2f, 0x6b, 0x50, 0x67, 0x7a, 0x41, 0x50, 0x42, 0x67, 0x4e, + 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x54, 0x41, + 0x44, 0x0a, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, + 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, + 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, 0x51, 0x42, 0x6f, 0x47, 0x77, + 0x57, 0x52, 0x30, 0x70, 0x4c, 0x4d, 0x31, 0x69, 0x63, 0x58, 0x34, 0x62, + 0x49, 0x4a, 0x36, 0x79, 0x64, 0x75, 0x46, 0x55, 0x2f, 0x41, 0x34, 0x6a, + 0x53, 0x69, 0x71, 0x45, 0x54, 0x36, 0x0a, 0x67, 0x76, 0x4a, 0x68, 0x77, + 0x67, 0x45, 0x72, 0x69, 0x6c, 0x71, 0x54, 0x4b, 0x66, 0x48, 0x36, 0x59, + 0x38, 0x39, 0x72, 0x71, 0x74, 0x7a, 0x57, 0x38, 0x6b, 0x34, 0x55, 0x75, + 0x72, 0x41, 0x4f, 0x43, 0x73, 0x45, 0x34, 0x46, 0x41, 0x36, 0x77, 0x62, + 0x6b, 0x48, 0x57, 0x77, 0x72, 0x55, 0x4d, 0x6e, 0x43, 0x6c, 0x59, 0x34, + 0x6c, 0x6b, 0x48, 0x4a, 0x68, 0x2b, 0x4d, 0x75, 0x4e, 0x61, 0x4a, 0x0a, + 0x6e, 0x43, 0x47, 0x72, 0x4b, 0x38, 0x77, 0x52, 0x4b, 0x47, 0x62, 0x2f, + 0x6d, 0x71, 0x57, 0x39, 0x64, 0x35, 0x70, 0x50, 0x37, 0x32, 0x45, 0x74, + 0x31, 0x51, 0x36, 0x4f, 0x57, 0x36, 0x44, 0x41, 0x4b, 0x71, 0x47, 0x66, + 0x6a, 0x44, 0x57, 0x68, 0x32, 0x4d, 0x7a, 0x53, 0x50, 0x48, 0x42, 0x78, + 0x63, 0x43, 0x4c, 0x65, 0x79, 0x69, 0x67, 0x4f, 0x31, 0x77, 0x71, 0x64, + 0x34, 0x57, 0x31, 0x54, 0x0a, 0x6e, 0x76, 0x76, 0x71, 0x6c, 0x36, 0x6c, + 0x34, 0x4c, 0x2b, 0x42, 0x35, 0x49, 0x54, 0x2f, 0x63, 0x2b, 0x2f, 0x45, + 0x48, 0x4f, 0x33, 0x50, 0x77, 0x62, 0x49, 0x39, 0x76, 0x36, 0x4d, 0x47, + 0x54, 0x74, 0x4c, 0x6a, 0x73, 0x5a, 0x67, 0x6b, 0x52, 0x4b, 0x49, 0x74, + 0x61, 0x50, 0x68, 0x2b, 0x59, 0x65, 0x4a, 0x64, 0x6d, 0x42, 0x59, 0x68, + 0x52, 0x44, 0x31, 0x42, 0x76, 0x57, 0x62, 0x36, 0x73, 0x0a, 0x56, 0x77, + 0x45, 0x62, 0x37, 0x61, 0x51, 0x31, 0x6f, 0x53, 0x46, 0x2b, 0x65, 0x73, + 0x55, 0x76, 0x4d, 0x6d, 0x6a, 0x47, 0x56, 0x75, 0x48, 0x58, 0x75, 0x51, + 0x76, 0x57, 0x4a, 0x61, 0x68, 0x6e, 0x6a, 0x59, 0x64, 0x59, 0x54, 0x32, + 0x44, 0x69, 0x6b, 0x79, 0x71, 0x52, 0x2b, 0x41, 0x77, 0x61, 0x4b, 0x7a, + 0x72, 0x65, 0x34, 0x47, 0x4a, 0x4d, 0x48, 0x73, 0x58, 0x33, 0x2f, 0x43, + 0x66, 0x38, 0x0a, 0x71, 0x64, 0x78, 0x79, 0x49, 0x2b, 0x42, 0x31, 0x6a, + 0x55, 0x77, 0x4e, 0x72, 0x37, 0x73, 0x4c, 0x41, 0x32, 0x45, 0x59, 0x44, + 0x6a, 0x6e, 0x55, 0x52, 0x30, 0x6a, 0x45, 0x48, 0x63, 0x72, 0x4f, 0x42, + 0x53, 0x70, 0x49, 0x51, 0x79, 0x52, 0x4d, 0x47, 0x57, 0x64, 0x75, 0x6a, + 0x30, 0x50, 0x31, 0x36, 0x79, 0x62, 0x39, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, + 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; extern const char test_self_signed_client_key[] = { 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x64, 0x77, 0x49, 0x42, + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x76, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, - 0x41, 0x6d, 0x45, 0x77, 0x67, 0x67, 0x4a, 0x64, 0x41, 0x67, 0x45, 0x41, - 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4c, 0x4a, 0x66, 0x59, 0x6e, 0x46, 0x6e, - 0x34, 0x6e, 0x6b, 0x6a, 0x35, 0x32, 0x57, 0x46, 0x0a, 0x45, 0x35, 0x57, - 0x32, 0x71, 0x55, 0x78, 0x43, 0x66, 0x6a, 0x73, 0x45, 0x46, 0x79, 0x75, - 0x58, 0x59, 0x59, 0x4b, 0x53, 0x2f, 0x30, 0x37, 0x55, 0x50, 0x57, 0x73, - 0x76, 0x33, 0x67, 0x70, 0x5a, 0x68, 0x74, 0x6a, 0x58, 0x67, 0x64, 0x65, - 0x47, 0x4c, 0x2b, 0x64, 0x70, 0x77, 0x45, 0x42, 0x43, 0x30, 0x49, 0x52, - 0x44, 0x42, 0x66, 0x47, 0x6e, 0x6b, 0x4d, 0x70, 0x36, 0x59, 0x59, 0x35, - 0x53, 0x0a, 0x4f, 0x37, 0x72, 0x6e, 0x45, 0x7a, 0x30, 0x58, 0x33, 0x72, - 0x2f, 0x66, 0x76, 0x67, 0x59, 0x79, 0x2b, 0x64, 0x45, 0x6c, 0x32, 0x6a, - 0x6e, 0x61, 0x41, 0x36, 0x7a, 0x67, 0x63, 0x37, 0x52, 0x7a, 0x4d, 0x47, - 0x6c, 0x39, 0x55, 0x31, 0x31, 0x64, 0x35, 0x36, 0x67, 0x50, 0x39, 0x46, - 0x69, 0x44, 0x43, 0x32, 0x31, 0x39, 0x30, 0x6d, 0x76, 0x50, 0x2f, 0x68, - 0x70, 0x71, 0x32, 0x78, 0x4c, 0x5a, 0x0a, 0x43, 0x54, 0x62, 0x49, 0x78, - 0x69, 0x6d, 0x70, 0x6d, 0x61, 0x6f, 0x51, 0x79, 0x78, 0x75, 0x75, 0x48, - 0x31, 0x62, 0x62, 0x59, 0x75, 0x6e, 0x65, 0x73, 0x49, 0x47, 0x2f, 0x41, - 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x43, 0x67, 0x59, 0x41, 0x64, 0x71, - 0x4a, 0x43, 0x45, 0x7a, 0x4d, 0x49, 0x79, 0x5a, 0x45, 0x37, 0x6f, 0x61, - 0x57, 0x30, 0x74, 0x4f, 0x70, 0x63, 0x42, 0x30, 0x42, 0x69, 0x50, 0x0a, - 0x46, 0x59, 0x6f, 0x49, 0x76, 0x48, 0x34, 0x42, 0x4b, 0x52, 0x48, 0x38, - 0x65, 0x48, 0x76, 0x52, 0x34, 0x37, 0x36, 0x6d, 0x74, 0x2b, 0x59, 0x64, - 0x44, 0x68, 0x42, 0x50, 0x31, 0x73, 0x63, 0x47, 0x55, 0x6d, 0x59, 0x65, - 0x43, 0x54, 0x34, 0x45, 0x6a, 0x2b, 0x52, 0x67, 0x48, 0x76, 0x32, 0x4c, - 0x50, 0x54, 0x67, 0x56, 0x59, 0x77, 0x54, 0x39, 0x65, 0x63, 0x69, 0x50, - 0x32, 0x2b, 0x45, 0x2f, 0x0a, 0x43, 0x42, 0x43, 0x4e, 0x52, 0x65, 0x6c, - 0x30, 0x53, 0x77, 0x39, 0x4a, 0x65, 0x70, 0x77, 0x57, 0x30, 0x72, 0x2b, - 0x6a, 0x57, 0x4a, 0x74, 0x44, 0x59, 0x31, 0x70, 0x70, 0x36, 0x59, 0x58, - 0x41, 0x67, 0x4e, 0x52, 0x47, 0x58, 0x32, 0x55, 0x66, 0x6c, 0x76, 0x55, - 0x73, 0x54, 0x2b, 0x6f, 0x39, 0x6c, 0x5a, 0x76, 0x61, 0x67, 0x66, 0x39, - 0x6d, 0x6f, 0x4c, 0x54, 0x4d, 0x79, 0x47, 0x76, 0x55, 0x0a, 0x75, 0x4c, - 0x46, 0x6e, 0x73, 0x79, 0x66, 0x4c, 0x69, 0x6d, 0x31, 0x42, 0x34, 0x76, - 0x58, 0x76, 0x57, 0x51, 0x4a, 0x42, 0x41, 0x4e, 0x6f, 0x75, 0x5a, 0x6c, - 0x6c, 0x58, 0x47, 0x5a, 0x6f, 0x53, 0x72, 0x5a, 0x4c, 0x74, 0x52, 0x33, - 0x56, 0x67, 0x56, 0x34, 0x74, 0x7a, 0x52, 0x51, 0x76, 0x4a, 0x78, 0x75, - 0x38, 0x34, 0x6b, 0x4c, 0x65, 0x49, 0x6b, 0x36, 0x34, 0x4f, 0x76, 0x34, - 0x37, 0x58, 0x0a, 0x70, 0x48, 0x56, 0x42, 0x4d, 0x54, 0x52, 0x42, 0x66, - 0x7a, 0x50, 0x45, 0x68, 0x62, 0x42, 0x6f, 0x64, 0x6a, 0x72, 0x31, 0x6d, - 0x35, 0x4f, 0x4c, 0x61, 0x56, 0x4c, 0x71, 0x6b, 0x46, 0x63, 0x58, 0x66, - 0x74, 0x7a, 0x52, 0x43, 0x72, 0x62, 0x57, 0x6f, 0x4b, 0x73, 0x43, 0x51, - 0x51, 0x44, 0x52, 0x53, 0x6f, 0x4c, 0x4c, 0x58, 0x4f, 0x69, 0x4c, 0x72, - 0x74, 0x4a, 0x33, 0x44, 0x4c, 0x4a, 0x43, 0x0a, 0x72, 0x58, 0x37, 0x59, - 0x38, 0x77, 0x72, 0x48, 0x5a, 0x72, 0x71, 0x6b, 0x35, 0x62, 0x4d, 0x64, - 0x5a, 0x4c, 0x47, 0x61, 0x2f, 0x55, 0x58, 0x38, 0x52, 0x61, 0x6e, 0x68, - 0x56, 0x77, 0x33, 0x2b, 0x58, 0x70, 0x2b, 0x75, 0x72, 0x64, 0x31, 0x37, - 0x31, 0x31, 0x75, 0x6d, 0x65, 0x4e, 0x4a, 0x66, 0x7a, 0x75, 0x2f, 0x4d, - 0x43, 0x6b, 0x34, 0x61, 0x31, 0x4b, 0x6b, 0x47, 0x2f, 0x43, 0x55, 0x30, - 0x0a, 0x72, 0x71, 0x73, 0x39, 0x41, 0x6b, 0x41, 0x34, 0x63, 0x53, 0x78, - 0x31, 0x44, 0x44, 0x31, 0x4a, 0x53, 0x47, 0x2b, 0x79, 0x78, 0x4d, 0x4e, - 0x70, 0x73, 0x41, 0x53, 0x31, 0x78, 0x4a, 0x6f, 0x6d, 0x46, 0x49, 0x72, - 0x73, 0x4d, 0x39, 0x76, 0x73, 0x50, 0x74, 0x37, 0x46, 0x64, 0x6e, 0x64, - 0x44, 0x77, 0x72, 0x46, 0x2b, 0x79, 0x2b, 0x43, 0x6f, 0x76, 0x68, 0x44, - 0x6b, 0x47, 0x59, 0x44, 0x6b, 0x0a, 0x52, 0x41, 0x48, 0x68, 0x2b, 0x73, - 0x76, 0x47, 0x66, 0x5a, 0x67, 0x2f, 0x70, 0x51, 0x4b, 0x32, 0x4a, 0x52, - 0x50, 0x69, 0x6d, 0x41, 0x6d, 0x48, 0x68, 0x7a, 0x71, 0x46, 0x41, 0x6b, - 0x45, 0x41, 0x75, 0x36, 0x59, 0x61, 0x37, 0x30, 0x73, 0x32, 0x46, 0x55, - 0x65, 0x42, 0x33, 0x4d, 0x75, 0x39, 0x61, 0x4a, 0x73, 0x32, 0x43, 0x44, - 0x36, 0x68, 0x67, 0x33, 0x64, 0x51, 0x45, 0x56, 0x6b, 0x42, 0x0a, 0x35, - 0x33, 0x44, 0x49, 0x37, 0x54, 0x58, 0x34, 0x38, 0x64, 0x39, 0x6b, 0x47, - 0x57, 0x35, 0x38, 0x56, 0x58, 0x31, 0x78, 0x6e, 0x71, 0x53, 0x30, 0x32, - 0x4c, 0x79, 0x57, 0x71, 0x41, 0x50, 0x63, 0x57, 0x35, 0x71, 0x6d, 0x31, - 0x6b, 0x4c, 0x48, 0x46, 0x4c, 0x64, 0x6e, 0x64, 0x61, 0x50, 0x4e, 0x6d, - 0x42, 0x61, 0x6a, 0x34, 0x51, 0x4a, 0x42, 0x41, 0x4a, 0x75, 0x67, 0x6c, - 0x33, 0x36, 0x37, 0x0a, 0x39, 0x64, 0x39, 0x74, 0x2f, 0x51, 0x4c, 0x54, - 0x53, 0x75, 0x55, 0x4c, 0x4c, 0x61, 0x6f, 0x59, 0x76, 0x32, 0x76, 0x4a, - 0x54, 0x33, 0x73, 0x31, 0x79, 0x39, 0x48, 0x4e, 0x38, 0x39, 0x45, 0x6f, - 0x61, 0x44, 0x44, 0x45, 0x6b, 0x50, 0x56, 0x66, 0x51, 0x75, 0x36, 0x47, - 0x56, 0x45, 0x58, 0x67, 0x49, 0x42, 0x74, 0x69, 0x6d, 0x31, 0x73, 0x49, - 0x2f, 0x56, 0x50, 0x53, 0x7a, 0x49, 0x38, 0x48, 0x0a, 0x61, 0x58, 0x76, - 0x61, 0x54, 0x55, 0x77, 0x62, 0x6c, 0x46, 0x57, 0x53, 0x4d, 0x37, 0x30, - 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, - 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; + 0x42, 0x4b, 0x67, 0x77, 0x67, 0x67, 0x53, 0x6b, 0x41, 0x67, 0x45, 0x41, + 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x76, 0x64, 0x7a, 0x4b, 0x44, + 0x54, 0x59, 0x76, 0x52, 0x67, 0x6a, 0x42, 0x4f, 0x0a, 0x55, 0x4f, 0x72, + 0x7a, 0x44, 0x77, 0x6b, 0x41, 0x5a, 0x47, 0x77, 0x4e, 0x46, 0x48, 0x48, + 0x6c, 0x4d, 0x59, 0x79, 0x4d, 0x47, 0x49, 0x35, 0x74, 0x49, 0x74, 0x6a, + 0x33, 0x74, 0x43, 0x7a, 0x58, 0x6b, 0x62, 0x70, 0x4d, 0x30, 0x75, 0x7a, + 0x33, 0x5a, 0x6a, 0x48, 0x56, 0x61, 0x68, 0x75, 0x2b, 0x65, 0x59, 0x63, + 0x2b, 0x4b, 0x76, 0x59, 0x41, 0x70, 0x4d, 0x36, 0x34, 0x46, 0x32, 0x64, + 0x42, 0x0a, 0x62, 0x31, 0x36, 0x68, 0x73, 0x37, 0x31, 0x33, 0x46, 0x43, + 0x6b, 0x38, 0x6d, 0x69, 0x68, 0x59, 0x41, 0x42, 0x6a, 0x6e, 0x53, 0x6e, + 0x64, 0x72, 0x51, 0x73, 0x6c, 0x2f, 0x55, 0x32, 0x76, 0x38, 0x59, 0x46, + 0x54, 0x37, 0x44, 0x69, 0x70, 0x66, 0x4c, 0x52, 0x65, 0x71, 0x71, 0x61, + 0x4f, 0x47, 0x75, 0x32, 0x6f, 0x39, 0x48, 0x64, 0x76, 0x57, 0x66, 0x69, + 0x55, 0x6c, 0x61, 0x69, 0x43, 0x2f, 0x0a, 0x55, 0x47, 0x47, 0x66, 0x52, + 0x2b, 0x59, 0x62, 0x6c, 0x70, 0x4b, 0x37, 0x43, 0x47, 0x2b, 0x37, 0x2f, + 0x68, 0x76, 0x54, 0x58, 0x74, 0x55, 0x73, 0x4d, 0x77, 0x2b, 0x4f, 0x70, + 0x70, 0x6f, 0x65, 0x48, 0x39, 0x7a, 0x38, 0x37, 0x72, 0x68, 0x4f, 0x4a, + 0x4d, 0x78, 0x74, 0x69, 0x43, 0x37, 0x58, 0x77, 0x55, 0x35, 0x72, 0x68, + 0x45, 0x6d, 0x61, 0x62, 0x2f, 0x31, 0x66, 0x31, 0x58, 0x4d, 0x2f, 0x0a, + 0x6e, 0x4c, 0x6f, 0x5a, 0x72, 0x66, 0x44, 0x41, 0x63, 0x54, 0x62, 0x44, + 0x79, 0x77, 0x6f, 0x65, 0x75, 0x38, 0x32, 0x36, 0x53, 0x4a, 0x33, 0x6d, + 0x69, 0x66, 0x61, 0x6a, 0x71, 0x37, 0x6f, 0x4b, 0x33, 0x4c, 0x44, 0x64, + 0x4e, 0x4c, 0x6a, 0x57, 0x5a, 0x77, 0x66, 0x45, 0x73, 0x43, 0x4f, 0x31, + 0x71, 0x70, 0x32, 0x43, 0x34, 0x67, 0x4c, 0x76, 0x42, 0x6c, 0x4f, 0x4f, + 0x4b, 0x73, 0x57, 0x4f, 0x0a, 0x4c, 0x4e, 0x62, 0x79, 0x36, 0x42, 0x79, + 0x78, 0x43, 0x4f, 0x50, 0x6c, 0x43, 0x54, 0x61, 0x30, 0x55, 0x43, 0x61, + 0x56, 0x75, 0x6f, 0x4e, 0x63, 0x6c, 0x59, 0x6f, 0x6c, 0x37, 0x31, 0x6a, + 0x79, 0x69, 0x31, 0x37, 0x4b, 0x57, 0x2b, 0x4e, 0x6b, 0x30, 0x6e, 0x4e, + 0x65, 0x39, 0x79, 0x61, 0x56, 0x63, 0x79, 0x72, 0x36, 0x48, 0x30, 0x7a, + 0x33, 0x62, 0x49, 0x6d, 0x66, 0x4a, 0x68, 0x62, 0x53, 0x0a, 0x75, 0x34, + 0x72, 0x7a, 0x49, 0x39, 0x33, 0x6e, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, + 0x45, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x4f, 0x49, 0x50, 0x4f, 0x4a, + 0x52, 0x54, 0x70, 0x47, 0x61, 0x48, 0x37, 0x47, 0x70, 0x43, 0x59, 0x55, + 0x70, 0x4c, 0x4b, 0x30, 0x67, 0x2f, 0x68, 0x50, 0x46, 0x6b, 0x46, 0x35, + 0x45, 0x79, 0x45, 0x57, 0x67, 0x2f, 0x31, 0x6c, 0x53, 0x59, 0x7a, 0x52, + 0x49, 0x70, 0x0a, 0x2b, 0x52, 0x73, 0x58, 0x36, 0x7a, 0x4f, 0x53, 0x2b, + 0x7a, 0x6b, 0x69, 0x4e, 0x48, 0x45, 0x76, 0x31, 0x6a, 0x6b, 0x65, 0x4b, + 0x4e, 0x6f, 0x37, 0x58, 0x44, 0x69, 0x48, 0x58, 0x4d, 0x37, 0x55, 0x36, + 0x52, 0x6b, 0x51, 0x74, 0x64, 0x6b, 0x5a, 0x41, 0x51, 0x64, 0x6b, 0x39, + 0x50, 0x6a, 0x4d, 0x33, 0x73, 0x45, 0x55, 0x64, 0x6d, 0x34, 0x43, 0x45, + 0x6e, 0x49, 0x6a, 0x66, 0x6d, 0x7a, 0x41, 0x0a, 0x70, 0x2f, 0x52, 0x38, + 0x54, 0x44, 0x30, 0x6b, 0x78, 0x6b, 0x4e, 0x4c, 0x49, 0x6b, 0x68, 0x75, + 0x46, 0x48, 0x32, 0x67, 0x64, 0x30, 0x35, 0x79, 0x33, 0x5a, 0x48, 0x44, + 0x53, 0x2f, 0x58, 0x69, 0x46, 0x6b, 0x41, 0x45, 0x39, 0x65, 0x4f, 0x54, + 0x30, 0x46, 0x72, 0x43, 0x37, 0x6f, 0x6d, 0x36, 0x45, 0x53, 0x44, 0x37, + 0x5a, 0x66, 0x46, 0x49, 0x57, 0x52, 0x31, 0x38, 0x70, 0x6e, 0x63, 0x57, + 0x0a, 0x5a, 0x47, 0x71, 0x37, 0x74, 0x46, 0x41, 0x5a, 0x5a, 0x52, 0x6d, + 0x70, 0x6b, 0x75, 0x6d, 0x32, 0x44, 0x2b, 0x4d, 0x4a, 0x79, 0x31, 0x67, + 0x57, 0x78, 0x49, 0x58, 0x42, 0x78, 0x74, 0x35, 0x6d, 0x61, 0x64, 0x54, + 0x45, 0x70, 0x52, 0x78, 0x51, 0x64, 0x35, 0x36, 0x74, 0x6f, 0x45, 0x6e, + 0x66, 0x78, 0x33, 0x37, 0x32, 0x46, 0x30, 0x79, 0x34, 0x7a, 0x6b, 0x63, + 0x58, 0x33, 0x70, 0x6e, 0x45, 0x0a, 0x34, 0x48, 0x36, 0x46, 0x61, 0x4a, + 0x55, 0x42, 0x6a, 0x64, 0x76, 0x4b, 0x6c, 0x32, 0x51, 0x7a, 0x46, 0x35, + 0x63, 0x30, 0x6a, 0x42, 0x71, 0x67, 0x78, 0x4d, 0x52, 0x76, 0x57, 0x50, + 0x35, 0x59, 0x66, 0x4e, 0x75, 0x38, 0x2b, 0x64, 0x6d, 0x61, 0x51, 0x4f, + 0x52, 0x50, 0x6b, 0x70, 0x7a, 0x53, 0x70, 0x74, 0x4f, 0x50, 0x6d, 0x5a, + 0x4d, 0x39, 0x56, 0x4b, 0x56, 0x2b, 0x74, 0x4a, 0x56, 0x53, 0x0a, 0x31, + 0x78, 0x6e, 0x4f, 0x49, 0x36, 0x44, 0x74, 0x72, 0x6e, 0x4e, 0x5a, 0x52, + 0x6f, 0x6a, 0x65, 0x67, 0x52, 0x2f, 0x45, 0x36, 0x4b, 0x68, 0x4e, 0x79, + 0x69, 0x50, 0x54, 0x59, 0x79, 0x39, 0x37, 0x55, 0x67, 0x59, 0x7a, 0x64, + 0x4b, 0x53, 0x2b, 0x53, 0x53, 0x45, 0x43, 0x67, 0x59, 0x45, 0x41, 0x2b, + 0x77, 0x67, 0x53, 0x49, 0x71, 0x72, 0x66, 0x6b, 0x65, 0x71, 0x71, 0x6f, + 0x74, 0x4a, 0x78, 0x0a, 0x63, 0x47, 0x78, 0x46, 0x34, 0x78, 0x39, 0x76, + 0x2f, 0x6c, 0x64, 0x4b, 0x72, 0x35, 0x68, 0x6c, 0x68, 0x4a, 0x4e, 0x6f, + 0x4b, 0x58, 0x4c, 0x6b, 0x65, 0x70, 0x6b, 0x63, 0x72, 0x76, 0x68, 0x68, + 0x78, 0x66, 0x48, 0x4b, 0x67, 0x6a, 0x57, 0x7a, 0x31, 0x6e, 0x5a, 0x59, + 0x2f, 0x2b, 0x52, 0x70, 0x67, 0x34, 0x32, 0x47, 0x46, 0x4d, 0x76, 0x78, + 0x57, 0x52, 0x72, 0x47, 0x54, 0x4d, 0x49, 0x4a, 0x0a, 0x64, 0x64, 0x69, + 0x4f, 0x72, 0x32, 0x34, 0x70, 0x30, 0x48, 0x43, 0x6b, 0x75, 0x73, 0x57, + 0x52, 0x4d, 0x4b, 0x51, 0x4c, 0x37, 0x58, 0x78, 0x76, 0x75, 0x48, 0x44, + 0x71, 0x30, 0x72, 0x6f, 0x38, 0x53, 0x47, 0x71, 0x58, 0x7a, 0x71, 0x57, + 0x47, 0x75, 0x48, 0x33, 0x31, 0x52, 0x2b, 0x59, 0x4e, 0x50, 0x38, 0x64, + 0x79, 0x32, 0x70, 0x71, 0x64, 0x33, 0x4f, 0x6c, 0x77, 0x7a, 0x54, 0x67, + 0x67, 0x0a, 0x38, 0x76, 0x30, 0x77, 0x77, 0x7a, 0x78, 0x38, 0x41, 0x75, + 0x79, 0x50, 0x35, 0x59, 0x73, 0x34, 0x4d, 0x32, 0x30, 0x45, 0x77, 0x76, + 0x37, 0x58, 0x75, 0x79, 0x30, 0x43, 0x67, 0x59, 0x45, 0x41, 0x39, 0x44, + 0x53, 0x47, 0x4d, 0x55, 0x38, 0x6a, 0x6d, 0x6a, 0x78, 0x4a, 0x2f, 0x75, + 0x50, 0x44, 0x43, 0x58, 0x57, 0x4f, 0x45, 0x41, 0x71, 0x74, 0x45, 0x37, + 0x38, 0x77, 0x54, 0x74, 0x49, 0x77, 0x0a, 0x75, 0x4d, 0x42, 0x76, 0x2b, + 0x67, 0x65, 0x30, 0x69, 0x6e, 0x63, 0x33, 0x37, 0x78, 0x66, 0x2b, 0x66, + 0x4e, 0x36, 0x44, 0x2f, 0x7a, 0x69, 0x54, 0x72, 0x4a, 0x76, 0x67, 0x77, + 0x2f, 0x58, 0x79, 0x54, 0x31, 0x35, 0x70, 0x6d, 0x51, 0x64, 0x4f, 0x6c, + 0x58, 0x78, 0x33, 0x53, 0x67, 0x31, 0x68, 0x39, 0x58, 0x42, 0x5a, 0x65, + 0x49, 0x6c, 0x61, 0x65, 0x43, 0x64, 0x46, 0x57, 0x72, 0x46, 0x42, 0x0a, + 0x6f, 0x59, 0x72, 0x56, 0x73, 0x69, 0x75, 0x6f, 0x58, 0x52, 0x73, 0x77, + 0x66, 0x6b, 0x46, 0x77, 0x41, 0x30, 0x79, 0x4f, 0x6b, 0x43, 0x73, 0x48, + 0x79, 0x47, 0x69, 0x49, 0x34, 0x54, 0x45, 0x30, 0x57, 0x31, 0x72, 0x47, + 0x62, 0x71, 0x50, 0x31, 0x35, 0x38, 0x49, 0x6a, 0x77, 0x58, 0x50, 0x63, + 0x7a, 0x42, 0x73, 0x77, 0x57, 0x49, 0x37, 0x69, 0x2f, 0x44, 0x36, 0x4c, + 0x70, 0x49, 0x4e, 0x4c, 0x0a, 0x42, 0x44, 0x37, 0x59, 0x59, 0x70, 0x66, + 0x48, 0x6d, 0x65, 0x4d, 0x43, 0x67, 0x59, 0x42, 0x30, 0x38, 0x41, 0x69, + 0x4b, 0x72, 0x37, 0x43, 0x66, 0x35, 0x34, 0x48, 0x2f, 0x67, 0x53, 0x71, + 0x6f, 0x35, 0x54, 0x63, 0x56, 0x47, 0x7a, 0x4c, 0x76, 0x64, 0x7a, 0x68, + 0x71, 0x58, 0x67, 0x4b, 0x45, 0x5a, 0x4b, 0x70, 0x30, 0x44, 0x48, 0x70, + 0x55, 0x68, 0x66, 0x69, 0x76, 0x70, 0x54, 0x4c, 0x65, 0x0a, 0x6f, 0x38, + 0x6a, 0x6a, 0x4b, 0x53, 0x4d, 0x53, 0x4e, 0x32, 0x55, 0x30, 0x4a, 0x76, + 0x48, 0x6a, 0x2f, 0x30, 0x78, 0x44, 0x61, 0x64, 0x47, 0x4f, 0x34, 0x59, + 0x4d, 0x59, 0x68, 0x4a, 0x63, 0x6c, 0x6c, 0x33, 0x43, 0x34, 0x56, 0x67, + 0x67, 0x53, 0x65, 0x6a, 0x61, 0x79, 0x62, 0x70, 0x41, 0x34, 0x36, 0x57, + 0x4a, 0x4a, 0x43, 0x64, 0x74, 0x39, 0x50, 0x74, 0x53, 0x55, 0x76, 0x33, + 0x36, 0x50, 0x0a, 0x65, 0x57, 0x41, 0x6f, 0x4f, 0x6b, 0x46, 0x73, 0x74, + 0x66, 0x68, 0x4a, 0x75, 0x75, 0x66, 0x58, 0x47, 0x78, 0x44, 0x73, 0x74, + 0x6e, 0x50, 0x74, 0x55, 0x61, 0x31, 0x6a, 0x57, 0x38, 0x38, 0x31, 0x67, + 0x69, 0x35, 0x78, 0x39, 0x44, 0x34, 0x4d, 0x6d, 0x71, 0x68, 0x5a, 0x6c, + 0x4b, 0x58, 0x6b, 0x68, 0x74, 0x64, 0x65, 0x41, 0x70, 0x72, 0x36, 0x4c, + 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x64, 0x0a, 0x49, 0x74, 0x73, 0x4a, + 0x74, 0x39, 0x4a, 0x54, 0x6a, 0x70, 0x69, 0x72, 0x47, 0x66, 0x43, 0x35, + 0x6c, 0x68, 0x77, 0x49, 0x35, 0x73, 0x49, 0x49, 0x43, 0x61, 0x39, 0x6a, + 0x45, 0x4f, 0x39, 0x52, 0x76, 0x65, 0x45, 0x6f, 0x6c, 0x75, 0x57, 0x6b, + 0x4a, 0x59, 0x55, 0x66, 0x47, 0x36, 0x6b, 0x31, 0x78, 0x67, 0x48, 0x64, + 0x6b, 0x59, 0x77, 0x59, 0x57, 0x43, 0x64, 0x58, 0x44, 0x46, 0x5a, 0x61, + 0x0a, 0x44, 0x50, 0x4b, 0x75, 0x77, 0x6e, 0x45, 0x6b, 0x36, 0x4d, 0x72, + 0x55, 0x34, 0x66, 0x31, 0x38, 0x31, 0x6a, 0x6f, 0x4f, 0x37, 0x73, 0x4a, + 0x66, 0x33, 0x35, 0x2f, 0x73, 0x47, 0x6d, 0x75, 0x47, 0x4c, 0x30, 0x53, + 0x48, 0x7a, 0x51, 0x54, 0x76, 0x47, 0x76, 0x6e, 0x30, 0x75, 0x71, 0x6b, + 0x47, 0x4d, 0x38, 0x4d, 0x39, 0x52, 0x64, 0x6f, 0x4d, 0x58, 0x71, 0x7a, + 0x6b, 0x7a, 0x7a, 0x76, 0x4d, 0x0a, 0x4a, 0x67, 0x31, 0x65, 0x6a, 0x31, + 0x62, 0x55, 0x67, 0x58, 0x63, 0x44, 0x62, 0x54, 0x6e, 0x61, 0x45, 0x68, + 0x7a, 0x62, 0x64, 0x4c, 0x69, 0x54, 0x46, 0x73, 0x67, 0x35, 0x4e, 0x7a, + 0x4d, 0x74, 0x4b, 0x77, 0x4f, 0x6a, 0x64, 0x44, 0x49, 0x70, 0x5a, 0x51, + 0x4b, 0x42, 0x67, 0x45, 0x49, 0x48, 0x65, 0x4a, 0x49, 0x71, 0x69, 0x47, + 0x6a, 0x59, 0x67, 0x66, 0x37, 0x6d, 0x55, 0x6c, 0x58, 0x32, 0x0a, 0x76, + 0x4e, 0x57, 0x67, 0x46, 0x4e, 0x6c, 0x7a, 0x41, 0x70, 0x6b, 0x46, 0x53, + 0x43, 0x51, 0x38, 0x54, 0x6b, 0x7a, 0x6b, 0x44, 0x4f, 0x6a, 0x74, 0x43, + 0x64, 0x53, 0x48, 0x66, 0x64, 0x52, 0x44, 0x4a, 0x36, 0x2b, 0x71, 0x38, + 0x63, 0x53, 0x32, 0x54, 0x53, 0x51, 0x37, 0x51, 0x50, 0x6f, 0x41, 0x6c, + 0x49, 0x31, 0x77, 0x6f, 0x53, 0x30, 0x47, 0x34, 0x38, 0x54, 0x4e, 0x62, + 0x56, 0x53, 0x6f, 0x0a, 0x77, 0x44, 0x30, 0x6a, 0x4e, 0x56, 0x52, 0x54, + 0x64, 0x70, 0x41, 0x36, 0x52, 0x35, 0x46, 0x50, 0x73, 0x67, 0x30, 0x39, + 0x6f, 0x68, 0x42, 0x2f, 0x63, 0x61, 0x53, 0x6e, 0x30, 0x7a, 0x6c, 0x47, + 0x56, 0x68, 0x61, 0x32, 0x47, 0x53, 0x30, 0x38, 0x63, 0x65, 0x59, 0x72, + 0x6e, 0x37, 0x6e, 0x6e, 0x34, 0x50, 0x53, 0x5a, 0x2f, 0x55, 0x49, 0x59, + 0x54, 0x6d, 0x33, 0x70, 0x6a, 0x55, 0x6c, 0x56, 0x0a, 0x48, 0x35, 0x74, + 0x76, 0x48, 0x76, 0x30, 0x67, 0x47, 0x32, 0x43, 0x35, 0x76, 0x79, 0x33, + 0x74, 0x49, 0x59, 0x51, 0x74, 0x53, 0x51, 0x43, 0x6b, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, + 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + 0x00}; extern const char test_signed_client_cert[] = { 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x48, 0x7a, 0x43, 0x43, - 0x41, 0x59, 0x67, 0x43, 0x41, 0x51, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4a, - 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, - 0x42, 0x51, 0x41, 0x77, 0x56, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, - 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x51, 0x56, 0x55, 0x78, - 0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56, 0x0a, 0x42, 0x41, 0x67, - 0x4d, 0x43, 0x6c, 0x4e, 0x76, 0x62, 0x57, 0x55, 0x74, 0x55, 0x33, 0x52, - 0x68, 0x64, 0x47, 0x55, 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, - 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x47, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, - 0x79, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x46, 0x64, 0x70, 0x5a, 0x47, 0x64, - 0x70, 0x64, 0x48, 0x4d, 0x67, 0x55, 0x48, 0x52, 0x35, 0x49, 0x45, 0x78, - 0x30, 0x0a, 0x5a, 0x44, 0x45, 0x50, 0x4d, 0x41, 0x30, 0x47, 0x41, 0x31, - 0x55, 0x45, 0x41, 0x77, 0x77, 0x47, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x47, - 0x4e, 0x68, 0x4d, 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x30, 0x4d, 0x44, - 0x63, 0x78, 0x4e, 0x7a, 0x49, 0x7a, 0x4e, 0x54, 0x59, 0x77, 0x4d, 0x6c, - 0x6f, 0x58, 0x44, 0x54, 0x49, 0x30, 0x4d, 0x44, 0x63, 0x78, 0x4e, 0x44, - 0x49, 0x7a, 0x4e, 0x54, 0x59, 0x77, 0x0a, 0x4d, 0x6c, 0x6f, 0x77, 0x57, - 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, - 0x68, 0x4d, 0x43, 0x51, 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42, - 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, 0x76, 0x62, - 0x57, 0x55, 0x74, 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x49, - 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x0a, - 0x47, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, 0x56, 0x30, - 0x49, 0x46, 0x64, 0x70, 0x5a, 0x47, 0x64, 0x70, 0x64, 0x48, 0x4d, 0x67, - 0x55, 0x48, 0x52, 0x35, 0x49, 0x45, 0x78, 0x30, 0x5a, 0x44, 0x45, 0x54, - 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x4b, - 0x64, 0x47, 0x56, 0x7a, 0x64, 0x47, 0x4e, 0x73, 0x61, 0x57, 0x56, 0x75, - 0x64, 0x44, 0x43, 0x42, 0x0a, 0x6e, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, - 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, - 0x46, 0x41, 0x41, 0x4f, 0x42, 0x6a, 0x51, 0x41, 0x77, 0x67, 0x59, 0x6b, - 0x43, 0x67, 0x59, 0x45, 0x41, 0x37, 0x46, 0x52, 0x48, 0x32, 0x36, 0x47, - 0x2b, 0x46, 0x74, 0x35, 0x56, 0x51, 0x67, 0x79, 0x7a, 0x6c, 0x5a, 0x73, - 0x66, 0x53, 0x6e, 0x48, 0x53, 0x5a, 0x36, 0x47, 0x58, 0x0a, 0x62, 0x37, - 0x71, 0x78, 0x6d, 0x6b, 0x32, 0x50, 0x4f, 0x38, 0x54, 0x59, 0x71, 0x4b, - 0x5a, 0x6d, 0x6b, 0x66, 0x4d, 0x77, 0x6b, 0x65, 0x36, 0x52, 0x55, 0x66, - 0x51, 0x56, 0x2b, 0x53, 0x2b, 0x47, 0x7a, 0x52, 0x76, 0x7a, 0x35, 0x4c, - 0x6c, 0x53, 0x33, 0x31, 0x55, 0x31, 0x51, 0x43, 0x70, 0x33, 0x63, 0x67, - 0x77, 0x6b, 0x49, 0x49, 0x41, 0x51, 0x61, 0x31, 0x45, 0x32, 0x68, 0x43, - 0x45, 0x7a, 0x0a, 0x57, 0x33, 0x31, 0x69, 0x76, 0x62, 0x4d, 0x42, 0x79, - 0x52, 0x4b, 0x39, 0x74, 0x46, 0x70, 0x79, 0x6e, 0x34, 0x55, 0x76, 0x38, - 0x4b, 0x50, 0x31, 0x34, 0x4f, 0x62, 0x4b, 0x6a, 0x54, 0x51, 0x71, 0x78, - 0x55, 0x5a, 0x70, 0x35, 0x35, 0x38, 0x44, 0x67, 0x4f, 0x48, 0x67, 0x35, - 0x62, 0x35, 0x6d, 0x47, 0x52, 0x4d, 0x30, 0x70, 0x79, 0x56, 0x31, 0x65, - 0x71, 0x52, 0x4b, 0x36, 0x50, 0x57, 0x77, 0x0a, 0x52, 0x2f, 0x62, 0x6a, - 0x67, 0x6c, 0x6c, 0x69, 0x36, 0x70, 0x6d, 0x6e, 0x72, 0x2b, 0x30, 0x43, - 0x41, 0x77, 0x45, 0x41, 0x41, 0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, - 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, - 0x41, 0x41, 0x4f, 0x42, 0x67, 0x51, 0x41, 0x53, 0x74, 0x53, 0x6d, 0x35, - 0x50, 0x4d, 0x37, 0x75, 0x62, 0x52, 0x4f, 0x69, 0x4b, 0x4b, 0x36, 0x2f, - 0x0a, 0x54, 0x32, 0x46, 0x6b, 0x4b, 0x6c, 0x68, 0x69, 0x54, 0x4f, 0x78, - 0x2b, 0x52, 0x79, 0x65, 0x6e, 0x6d, 0x33, 0x45, 0x69, 0x6f, 0x35, 0x39, - 0x65, 0x6d, 0x71, 0x2b, 0x6a, 0x58, 0x6c, 0x2b, 0x31, 0x6e, 0x68, 0x50, - 0x79, 0x53, 0x58, 0x35, 0x47, 0x32, 0x50, 0x51, 0x7a, 0x53, 0x52, 0x35, - 0x76, 0x64, 0x31, 0x64, 0x49, 0x68, 0x77, 0x67, 0x5a, 0x53, 0x52, 0x34, - 0x47, 0x79, 0x74, 0x74, 0x6b, 0x0a, 0x74, 0x52, 0x5a, 0x35, 0x37, 0x6b, - 0x2f, 0x4e, 0x49, 0x31, 0x62, 0x72, 0x55, 0x57, 0x38, 0x6a, 0x6f, 0x69, - 0x45, 0x4f, 0x4d, 0x4a, 0x41, 0x2f, 0x4d, 0x72, 0x37, 0x48, 0x37, 0x61, - 0x73, 0x78, 0x37, 0x77, 0x49, 0x52, 0x59, 0x44, 0x45, 0x39, 0x31, 0x46, - 0x73, 0x38, 0x47, 0x6b, 0x4b, 0x57, 0x64, 0x35, 0x4c, 0x68, 0x6f, 0x50, - 0x41, 0x51, 0x6a, 0x2b, 0x71, 0x64, 0x47, 0x33, 0x35, 0x43, 0x0a, 0x4f, - 0x4f, 0x2b, 0x73, 0x76, 0x64, 0x6b, 0x6d, 0x71, 0x48, 0x30, 0x4b, 0x5a, - 0x6f, 0x33, 0x32, 0x30, 0x5a, 0x55, 0x71, 0x64, 0x6c, 0x32, 0x6f, 0x6f, - 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, - 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x4e, 0x7a, 0x43, 0x43, + 0x41, 0x68, 0x38, 0x43, 0x46, 0x47, 0x79, 0x58, 0x30, 0x30, 0x52, 0x43, + 0x65, 0x70, 0x4f, 0x76, 0x2f, 0x71, 0x43, 0x4a, 0x31, 0x6f, 0x56, 0x64, + 0x54, 0x74, 0x59, 0x39, 0x32, 0x55, 0x38, 0x33, 0x4d, 0x41, 0x30, 0x47, + 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, + 0x43, 0x77, 0x55, 0x41, 0x4d, 0x46, 0x59, 0x78, 0x0a, 0x43, 0x7a, 0x41, + 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6b, 0x46, + 0x56, 0x4d, 0x52, 0x4d, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, + 0x49, 0x44, 0x41, 0x70, 0x54, 0x62, 0x32, 0x31, 0x6c, 0x4c, 0x56, 0x4e, + 0x30, 0x59, 0x58, 0x52, 0x6c, 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, + 0x44, 0x56, 0x51, 0x51, 0x4b, 0x44, 0x42, 0x68, 0x4a, 0x62, 0x6e, 0x52, + 0x6c, 0x0a, 0x63, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42, 0x58, 0x61, 0x57, + 0x52, 0x6e, 0x61, 0x58, 0x52, 0x7a, 0x49, 0x46, 0x42, 0x30, 0x65, 0x53, + 0x42, 0x4d, 0x64, 0x47, 0x51, 0x78, 0x44, 0x7a, 0x41, 0x4e, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x42, 0x6e, 0x52, 0x6c, 0x63, 0x33, + 0x52, 0x6a, 0x59, 0x54, 0x41, 0x65, 0x46, 0x77, 0x30, 0x79, 0x4d, 0x44, + 0x41, 0x7a, 0x4d, 0x54, 0x67, 0x77, 0x0a, 0x4d, 0x54, 0x41, 0x32, 0x4d, + 0x54, 0x42, 0x61, 0x46, 0x77, 0x30, 0x7a, 0x4d, 0x44, 0x41, 0x7a, 0x4d, + 0x54, 0x59, 0x77, 0x4d, 0x54, 0x41, 0x32, 0x4d, 0x54, 0x42, 0x61, 0x4d, + 0x46, 0x6f, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, + 0x41, 0x59, 0x54, 0x41, 0x6b, 0x46, 0x56, 0x4d, 0x52, 0x4d, 0x77, 0x45, + 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x70, 0x54, 0x0a, + 0x62, 0x32, 0x31, 0x6c, 0x4c, 0x56, 0x4e, 0x30, 0x59, 0x58, 0x52, 0x6c, + 0x4d, 0x53, 0x45, 0x77, 0x48, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, + 0x44, 0x42, 0x68, 0x4a, 0x62, 0x6e, 0x52, 0x6c, 0x63, 0x6d, 0x35, 0x6c, + 0x64, 0x43, 0x42, 0x58, 0x61, 0x57, 0x52, 0x6e, 0x61, 0x58, 0x52, 0x7a, + 0x49, 0x46, 0x42, 0x30, 0x65, 0x53, 0x42, 0x4d, 0x64, 0x47, 0x51, 0x78, + 0x45, 0x7a, 0x41, 0x52, 0x0a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, + 0x4d, 0x43, 0x6e, 0x52, 0x6c, 0x63, 0x33, 0x52, 0x6a, 0x62, 0x47, 0x6c, + 0x6c, 0x62, 0x6e, 0x51, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30, + 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, + 0x42, 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, + 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x0a, 0x41, 0x51, + 0x43, 0x79, 0x71, 0x59, 0x52, 0x70, 0x2b, 0x44, 0x58, 0x56, 0x70, 0x37, + 0x32, 0x4e, 0x46, 0x62, 0x51, 0x48, 0x38, 0x68, 0x64, 0x68, 0x54, 0x5a, + 0x4c, 0x79, 0x63, 0x5a, 0x58, 0x4f, 0x6c, 0x4a, 0x68, 0x6d, 0x4d, 0x73, + 0x72, 0x4a, 0x6d, 0x72, 0x6a, 0x6e, 0x32, 0x70, 0x37, 0x70, 0x49, 0x2f, + 0x38, 0x6d, 0x54, 0x5a, 0x2f, 0x30, 0x46, 0x43, 0x2b, 0x53, 0x47, 0x57, + 0x42, 0x47, 0x0a, 0x5a, 0x56, 0x2b, 0x45, 0x4c, 0x69, 0x48, 0x72, 0x6d, + 0x43, 0x58, 0x35, 0x7a, 0x66, 0x61, 0x49, 0x4c, 0x72, 0x39, 0x49, 0x75, + 0x77, 0x37, 0x47, 0x68, 0x72, 0x33, 0x56, 0x7a, 0x6f, 0x65, 0x66, 0x69, + 0x38, 0x72, 0x36, 0x32, 0x72, 0x4c, 0x75, 0x70, 0x56, 0x50, 0x4e, 0x69, + 0x2f, 0x71, 0x64, 0x71, 0x79, 0x6a, 0x57, 0x6b, 0x32, 0x64, 0x45, 0x43, + 0x48, 0x43, 0x39, 0x5a, 0x33, 0x2b, 0x41, 0x0a, 0x67, 0x33, 0x4b, 0x7a, + 0x4b, 0x54, 0x79, 0x65, 0x72, 0x58, 0x57, 0x6a, 0x4b, 0x63, 0x76, 0x79, + 0x4b, 0x56, 0x6d, 0x4d, 0x30, 0x5a, 0x78, 0x45, 0x30, 0x52, 0x58, 0x68, + 0x44, 0x57, 0x2f, 0x52, 0x6f, 0x51, 0x62, 0x71, 0x5a, 0x73, 0x55, 0x32, + 0x47, 0x4b, 0x67, 0x31, 0x42, 0x32, 0x72, 0x68, 0x55, 0x55, 0x38, 0x4b, + 0x4e, 0x30, 0x67, 0x56, 0x6d, 0x4b, 0x6e, 0x30, 0x72, 0x4a, 0x48, 0x4f, + 0x0a, 0x78, 0x7a, 0x52, 0x56, 0x53, 0x59, 0x65, 0x59, 0x4c, 0x59, 0x70, + 0x35, 0x59, 0x6e, 0x37, 0x4b, 0x72, 0x74, 0x50, 0x4a, 0x63, 0x4b, 0x79, + 0x6f, 0x39, 0x61, 0x56, 0x75, 0x45, 0x72, 0x37, 0x64, 0x47, 0x41, 0x4e, + 0x7a, 0x70, 0x79, 0x46, 0x36, 0x6c, 0x67, 0x2f, 0x6e, 0x59, 0x42, 0x57, + 0x63, 0x2b, 0x39, 0x53, 0x47, 0x77, 0x6b, 0x6f, 0x4c, 0x64, 0x46, 0x76, + 0x4b, 0x76, 0x41, 0x42, 0x59, 0x0a, 0x4a, 0x4d, 0x79, 0x72, 0x62, 0x4e, + 0x68, 0x48, 0x55, 0x51, 0x66, 0x76, 0x30, 0x66, 0x7a, 0x61, 0x5a, 0x30, + 0x50, 0x38, 0x36, 0x64, 0x66, 0x54, 0x45, 0x4e, 0x72, 0x44, 0x78, 0x7a, + 0x41, 0x4c, 0x72, 0x7a, 0x47, 0x6e, 0x71, 0x63, 0x78, 0x33, 0x4b, 0x54, + 0x72, 0x77, 0x4a, 0x6a, 0x6b, 0x5a, 0x2f, 0x61, 0x53, 0x72, 0x31, 0x74, + 0x79, 0x44, 0x30, 0x2f, 0x74, 0x58, 0x76, 0x75, 0x6b, 0x52, 0x0a, 0x46, + 0x69, 0x50, 0x78, 0x57, 0x42, 0x4a, 0x68, 0x6a, 0x48, 0x51, 0x37, 0x30, + 0x47, 0x71, 0x54, 0x46, 0x51, 0x59, 0x31, 0x39, 0x52, 0x62, 0x68, 0x41, + 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, + 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, + 0x51, 0x41, 0x44, 0x67, 0x67, 0x45, 0x42, 0x41, 0x46, 0x58, 0x43, 0x65, + 0x77, 0x4b, 0x38, 0x0a, 0x63, 0x57, 0x54, 0x2b, 0x7a, 0x57, 0x78, 0x58, + 0x79, 0x47, 0x46, 0x6e, 0x6f, 0x75, 0x46, 0x53, 0x42, 0x7a, 0x54, 0x69, + 0x30, 0x42, 0x4d, 0x42, 0x4a, 0x52, 0x72, 0x68, 0x73, 0x69, 0x4e, 0x6f, + 0x69, 0x51, 0x78, 0x6b, 0x71, 0x69, 0x74, 0x79, 0x4a, 0x48, 0x57, 0x46, + 0x45, 0x78, 0x69, 0x51, 0x5a, 0x69, 0x65, 0x2b, 0x37, 0x43, 0x41, 0x2b, + 0x45, 0x61, 0x62, 0x58, 0x43, 0x51, 0x55, 0x42, 0x0a, 0x2b, 0x4a, 0x77, + 0x4d, 0x53, 0x57, 0x4d, 0x32, 0x39, 0x6a, 0x33, 0x6d, 0x53, 0x77, 0x31, + 0x30, 0x44, 0x54, 0x66, 0x6d, 0x43, 0x33, 0x72, 0x68, 0x68, 0x65, 0x51, + 0x71, 0x47, 0x78, 0x79, 0x33, 0x30, 0x34, 0x42, 0x5a, 0x79, 0x55, 0x70, + 0x64, 0x70, 0x76, 0x49, 0x32, 0x64, 0x74, 0x33, 0x70, 0x2f, 0x6d, 0x63, + 0x73, 0x45, 0x37, 0x4f, 0x2b, 0x70, 0x34, 0x73, 0x51, 0x72, 0x53, 0x65, + 0x70, 0x0a, 0x67, 0x69, 0x6a, 0x69, 0x44, 0x73, 0x73, 0x4b, 0x41, 0x66, + 0x78, 0x54, 0x41, 0x6d, 0x55, 0x4d, 0x39, 0x33, 0x4e, 0x36, 0x2b, 0x51, + 0x38, 0x79, 0x4a, 0x4b, 0x35, 0x69, 0x6d, 0x6d, 0x78, 0x6c, 0x62, 0x65, + 0x59, 0x66, 0x69, 0x6a, 0x6f, 0x42, 0x76, 0x6d, 0x6b, 0x7a, 0x79, 0x42, + 0x2f, 0x42, 0x2b, 0x71, 0x4e, 0x52, 0x50, 0x73, 0x78, 0x30, 0x6e, 0x37, + 0x61, 0x46, 0x47, 0x6e, 0x66, 0x76, 0x0a, 0x6f, 0x57, 0x66, 0x6b, 0x57, + 0x32, 0x39, 0x36, 0x69, 0x50, 0x68, 0x57, 0x4c, 0x69, 0x77, 0x6b, 0x6e, + 0x70, 0x43, 0x33, 0x78, 0x42, 0x36, 0x6f, 0x4b, 0x33, 0x76, 0x52, 0x62, + 0x4b, 0x34, 0x5a, 0x6a, 0x31, 0x4f, 0x61, 0x47, 0x62, 0x30, 0x67, 0x72, + 0x4b, 0x37, 0x56, 0x4e, 0x38, 0x45, 0x79, 0x68, 0x42, 0x69, 0x78, 0x32, + 0x78, 0x56, 0x46, 0x36, 0x31, 0x69, 0x34, 0x64, 0x7a, 0x43, 0x4b, 0x0a, + 0x6b, 0x4d, 0x49, 0x70, 0x6c, 0x37, 0x43, 0x55, 0x70, 0x77, 0x31, 0x4d, + 0x62, 0x32, 0x7a, 0x38, 0x71, 0x33, 0x46, 0x32, 0x62, 0x48, 0x42, 0x53, + 0x37, 0x69, 0x46, 0x37, 0x67, 0x31, 0x43, 0x63, 0x6e, 0x35, 0x56, 0x47, + 0x63, 0x4f, 0x2b, 0x61, 0x4a, 0x2b, 0x36, 0x50, 0x57, 0x79, 0x64, 0x61, + 0x65, 0x71, 0x4a, 0x36, 0x56, 0x45, 0x42, 0x46, 0x30, 0x4e, 0x77, 0x76, + 0x39, 0x77, 0x6f, 0x65, 0x0a, 0x6d, 0x4c, 0x35, 0x41, 0x6c, 0x75, 0x4e, + 0x52, 0x4c, 0x61, 0x71, 0x6a, 0x5a, 0x76, 0x45, 0x3d, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, + 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + 0x00}; extern const char test_signed_client_key[] = { 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x65, 0x51, 0x49, 0x42, + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x76, 0x67, 0x49, 0x42, 0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, - 0x41, 0x6d, 0x4d, 0x77, 0x67, 0x67, 0x4a, 0x66, 0x41, 0x67, 0x45, 0x41, - 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4f, 0x78, 0x55, 0x52, 0x39, 0x75, 0x68, - 0x76, 0x68, 0x62, 0x65, 0x56, 0x55, 0x49, 0x4d, 0x0a, 0x73, 0x35, 0x57, - 0x62, 0x48, 0x30, 0x70, 0x78, 0x30, 0x6d, 0x65, 0x68, 0x6c, 0x32, 0x2b, - 0x36, 0x73, 0x5a, 0x70, 0x4e, 0x6a, 0x7a, 0x76, 0x45, 0x32, 0x4b, 0x69, - 0x6d, 0x5a, 0x70, 0x48, 0x7a, 0x4d, 0x4a, 0x48, 0x75, 0x6b, 0x56, 0x48, - 0x30, 0x46, 0x66, 0x6b, 0x76, 0x68, 0x73, 0x30, 0x62, 0x38, 0x2b, 0x53, - 0x35, 0x55, 0x74, 0x39, 0x56, 0x4e, 0x55, 0x41, 0x71, 0x64, 0x33, 0x49, - 0x4d, 0x0a, 0x4a, 0x43, 0x43, 0x41, 0x45, 0x47, 0x74, 0x52, 0x4e, 0x6f, - 0x51, 0x68, 0x4d, 0x31, 0x74, 0x39, 0x59, 0x72, 0x32, 0x7a, 0x41, 0x63, - 0x6b, 0x53, 0x76, 0x62, 0x52, 0x61, 0x63, 0x70, 0x2b, 0x46, 0x4c, 0x2f, - 0x43, 0x6a, 0x39, 0x65, 0x44, 0x6d, 0x79, 0x6f, 0x30, 0x30, 0x4b, 0x73, - 0x56, 0x47, 0x61, 0x65, 0x65, 0x66, 0x41, 0x34, 0x44, 0x68, 0x34, 0x4f, - 0x57, 0x2b, 0x5a, 0x68, 0x6b, 0x54, 0x0a, 0x4e, 0x4b, 0x63, 0x6c, 0x64, - 0x58, 0x71, 0x6b, 0x53, 0x75, 0x6a, 0x31, 0x73, 0x45, 0x66, 0x32, 0x34, - 0x34, 0x4a, 0x5a, 0x59, 0x75, 0x71, 0x5a, 0x70, 0x36, 0x2f, 0x74, 0x41, - 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x43, 0x67, 0x59, 0x45, 0x41, 0x69, - 0x32, 0x4e, 0x53, 0x56, 0x71, 0x70, 0x5a, 0x4d, 0x61, 0x66, 0x45, 0x35, - 0x59, 0x59, 0x55, 0x54, 0x63, 0x4d, 0x47, 0x65, 0x36, 0x51, 0x53, 0x0a, - 0x6b, 0x32, 0x6a, 0x74, 0x70, 0x73, 0x71, 0x59, 0x67, 0x67, 0x67, 0x49, - 0x32, 0x52, 0x6e, 0x4c, 0x4a, 0x2f, 0x32, 0x74, 0x4e, 0x5a, 0x77, 0x59, - 0x49, 0x35, 0x70, 0x77, 0x50, 0x38, 0x51, 0x56, 0x53, 0x62, 0x6e, 0x4d, - 0x61, 0x69, 0x46, 0x34, 0x67, 0x6f, 0x6b, 0x44, 0x35, 0x68, 0x47, 0x64, - 0x72, 0x4e, 0x44, 0x66, 0x54, 0x6e, 0x62, 0x32, 0x76, 0x2b, 0x79, 0x49, - 0x77, 0x59, 0x45, 0x48, 0x0a, 0x30, 0x77, 0x38, 0x2b, 0x6f, 0x47, 0x37, - 0x5a, 0x38, 0x31, 0x4b, 0x6f, 0x64, 0x73, 0x69, 0x5a, 0x53, 0x49, 0x44, - 0x4a, 0x66, 0x54, 0x47, 0x73, 0x41, 0x5a, 0x68, 0x56, 0x4e, 0x77, 0x4f, - 0x7a, 0x39, 0x79, 0x30, 0x56, 0x44, 0x38, 0x42, 0x42, 0x5a, 0x5a, 0x31, - 0x2f, 0x32, 0x37, 0x34, 0x5a, 0x68, 0x35, 0x32, 0x41, 0x55, 0x4b, 0x4c, - 0x6a, 0x5a, 0x53, 0x2f, 0x5a, 0x77, 0x49, 0x62, 0x53, 0x0a, 0x57, 0x32, - 0x79, 0x77, 0x79, 0x61, 0x38, 0x35, 0x35, 0x64, 0x50, 0x6e, 0x48, 0x2f, - 0x77, 0x6a, 0x2b, 0x30, 0x45, 0x43, 0x51, 0x51, 0x44, 0x39, 0x58, 0x38, - 0x44, 0x39, 0x32, 0x30, 0x6b, 0x42, 0x79, 0x54, 0x4e, 0x48, 0x68, 0x42, - 0x47, 0x31, 0x38, 0x62, 0x69, 0x41, 0x45, 0x5a, 0x34, 0x70, 0x78, 0x73, - 0x39, 0x66, 0x30, 0x4f, 0x41, 0x47, 0x38, 0x33, 0x33, 0x33, 0x65, 0x56, - 0x63, 0x49, 0x0a, 0x77, 0x32, 0x6c, 0x4a, 0x44, 0x4c, 0x73, 0x59, 0x44, - 0x5a, 0x72, 0x43, 0x42, 0x32, 0x6f, 0x63, 0x67, 0x41, 0x33, 0x6c, 0x55, - 0x64, 0x6f, 0x7a, 0x6c, 0x7a, 0x50, 0x43, 0x37, 0x59, 0x44, 0x59, 0x77, - 0x38, 0x72, 0x65, 0x67, 0x30, 0x74, 0x6b, 0x69, 0x52, 0x59, 0x35, 0x41, - 0x6b, 0x45, 0x41, 0x37, 0x73, 0x64, 0x4e, 0x7a, 0x4f, 0x65, 0x51, 0x73, - 0x51, 0x52, 0x6e, 0x37, 0x2b, 0x2b, 0x35, 0x0a, 0x30, 0x62, 0x50, 0x39, - 0x44, 0x74, 0x54, 0x2f, 0x69, 0x4f, 0x4e, 0x31, 0x67, 0x62, 0x66, 0x78, - 0x52, 0x7a, 0x43, 0x66, 0x43, 0x66, 0x58, 0x64, 0x6f, 0x4f, 0x74, 0x66, - 0x51, 0x57, 0x49, 0x7a, 0x54, 0x65, 0x50, 0x57, 0x74, 0x55, 0x52, 0x74, - 0x39, 0x58, 0x2f, 0x35, 0x44, 0x39, 0x4e, 0x6f, 0x66, 0x49, 0x30, 0x52, - 0x67, 0x35, 0x57, 0x32, 0x6f, 0x47, 0x79, 0x2f, 0x4d, 0x4c, 0x65, 0x35, - 0x0a, 0x2f, 0x73, 0x58, 0x48, 0x56, 0x51, 0x4a, 0x42, 0x41, 0x49, 0x75, - 0x70, 0x35, 0x58, 0x72, 0x4a, 0x44, 0x6b, 0x51, 0x79, 0x77, 0x4e, 0x5a, - 0x79, 0x41, 0x55, 0x55, 0x32, 0x65, 0x63, 0x6e, 0x32, 0x62, 0x43, 0x57, - 0x42, 0x46, 0x6a, 0x77, 0x74, 0x71, 0x64, 0x2b, 0x4c, 0x42, 0x6d, 0x75, - 0x4d, 0x63, 0x69, 0x49, 0x39, 0x66, 0x4f, 0x4b, 0x73, 0x5a, 0x74, 0x45, - 0x4b, 0x5a, 0x72, 0x7a, 0x2f, 0x0a, 0x55, 0x30, 0x6c, 0x6b, 0x65, 0x4d, - 0x52, 0x6f, 0x53, 0x77, 0x76, 0x58, 0x45, 0x38, 0x77, 0x6d, 0x47, 0x4c, - 0x6a, 0x6a, 0x72, 0x41, 0x62, 0x64, 0x66, 0x6f, 0x68, 0x72, 0x58, 0x46, - 0x6b, 0x43, 0x51, 0x51, 0x44, 0x5a, 0x45, 0x78, 0x2f, 0x4c, 0x74, 0x49, - 0x6c, 0x36, 0x4a, 0x49, 0x4e, 0x4a, 0x51, 0x69, 0x73, 0x77, 0x56, 0x65, - 0x30, 0x74, 0x57, 0x72, 0x36, 0x6b, 0x2b, 0x41, 0x53, 0x50, 0x0a, 0x31, - 0x57, 0x58, 0x6f, 0x54, 0x6d, 0x2b, 0x48, 0x59, 0x70, 0x6f, 0x46, 0x2f, - 0x58, 0x55, 0x76, 0x76, 0x39, 0x4c, 0x63, 0x63, 0x4e, 0x46, 0x31, 0x49, - 0x61, 0x7a, 0x46, 0x6a, 0x33, 0x34, 0x68, 0x77, 0x52, 0x51, 0x77, 0x68, - 0x78, 0x37, 0x77, 0x2f, 0x56, 0x35, 0x32, 0x49, 0x65, 0x62, 0x2b, 0x70, - 0x30, 0x6a, 0x55, 0x4d, 0x59, 0x47, 0x78, 0x41, 0x6b, 0x45, 0x41, 0x6a, - 0x44, 0x68, 0x64, 0x0a, 0x39, 0x70, 0x42, 0x4f, 0x31, 0x66, 0x4b, 0x58, - 0x57, 0x69, 0x58, 0x7a, 0x69, 0x39, 0x5a, 0x4b, 0x66, 0x6f, 0x79, 0x54, - 0x4e, 0x63, 0x55, 0x71, 0x33, 0x65, 0x42, 0x53, 0x56, 0x4b, 0x77, 0x50, - 0x47, 0x32, 0x6e, 0x49, 0x74, 0x67, 0x35, 0x79, 0x63, 0x58, 0x65, 0x6e, - 0x67, 0x6a, 0x54, 0x35, 0x73, 0x67, 0x63, 0x57, 0x44, 0x6e, 0x63, 0x69, - 0x49, 0x7a, 0x57, 0x37, 0x42, 0x49, 0x56, 0x49, 0x0a, 0x4a, 0x69, 0x71, - 0x4f, 0x73, 0x7a, 0x71, 0x39, 0x47, 0x57, 0x45, 0x53, 0x45, 0x72, 0x41, - 0x61, 0x74, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, - 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, - 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; + 0x42, 0x4b, 0x67, 0x77, 0x67, 0x67, 0x53, 0x6b, 0x41, 0x67, 0x45, 0x41, + 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x43, 0x79, 0x71, 0x59, 0x52, 0x70, + 0x2b, 0x44, 0x58, 0x56, 0x70, 0x37, 0x32, 0x4e, 0x0a, 0x46, 0x62, 0x51, + 0x48, 0x38, 0x68, 0x64, 0x68, 0x54, 0x5a, 0x4c, 0x79, 0x63, 0x5a, 0x58, + 0x4f, 0x6c, 0x4a, 0x68, 0x6d, 0x4d, 0x73, 0x72, 0x4a, 0x6d, 0x72, 0x6a, + 0x6e, 0x32, 0x70, 0x37, 0x70, 0x49, 0x2f, 0x38, 0x6d, 0x54, 0x5a, 0x2f, + 0x30, 0x46, 0x43, 0x2b, 0x53, 0x47, 0x57, 0x42, 0x47, 0x5a, 0x56, 0x2b, + 0x45, 0x4c, 0x69, 0x48, 0x72, 0x6d, 0x43, 0x58, 0x35, 0x7a, 0x66, 0x61, + 0x49, 0x0a, 0x4c, 0x72, 0x39, 0x49, 0x75, 0x77, 0x37, 0x47, 0x68, 0x72, + 0x33, 0x56, 0x7a, 0x6f, 0x65, 0x66, 0x69, 0x38, 0x72, 0x36, 0x32, 0x72, + 0x4c, 0x75, 0x70, 0x56, 0x50, 0x4e, 0x69, 0x2f, 0x71, 0x64, 0x71, 0x79, + 0x6a, 0x57, 0x6b, 0x32, 0x64, 0x45, 0x43, 0x48, 0x43, 0x39, 0x5a, 0x33, + 0x2b, 0x41, 0x67, 0x33, 0x4b, 0x7a, 0x4b, 0x54, 0x79, 0x65, 0x72, 0x58, + 0x57, 0x6a, 0x4b, 0x63, 0x76, 0x79, 0x0a, 0x4b, 0x56, 0x6d, 0x4d, 0x30, + 0x5a, 0x78, 0x45, 0x30, 0x52, 0x58, 0x68, 0x44, 0x57, 0x2f, 0x52, 0x6f, + 0x51, 0x62, 0x71, 0x5a, 0x73, 0x55, 0x32, 0x47, 0x4b, 0x67, 0x31, 0x42, + 0x32, 0x72, 0x68, 0x55, 0x55, 0x38, 0x4b, 0x4e, 0x30, 0x67, 0x56, 0x6d, + 0x4b, 0x6e, 0x30, 0x72, 0x4a, 0x48, 0x4f, 0x78, 0x7a, 0x52, 0x56, 0x53, + 0x59, 0x65, 0x59, 0x4c, 0x59, 0x70, 0x35, 0x59, 0x6e, 0x37, 0x4b, 0x0a, + 0x72, 0x74, 0x50, 0x4a, 0x63, 0x4b, 0x79, 0x6f, 0x39, 0x61, 0x56, 0x75, + 0x45, 0x72, 0x37, 0x64, 0x47, 0x41, 0x4e, 0x7a, 0x70, 0x79, 0x46, 0x36, + 0x6c, 0x67, 0x2f, 0x6e, 0x59, 0x42, 0x57, 0x63, 0x2b, 0x39, 0x53, 0x47, + 0x77, 0x6b, 0x6f, 0x4c, 0x64, 0x46, 0x76, 0x4b, 0x76, 0x41, 0x42, 0x59, + 0x4a, 0x4d, 0x79, 0x72, 0x62, 0x4e, 0x68, 0x48, 0x55, 0x51, 0x66, 0x76, + 0x30, 0x66, 0x7a, 0x61, 0x0a, 0x5a, 0x30, 0x50, 0x38, 0x36, 0x64, 0x66, + 0x54, 0x45, 0x4e, 0x72, 0x44, 0x78, 0x7a, 0x41, 0x4c, 0x72, 0x7a, 0x47, + 0x6e, 0x71, 0x63, 0x78, 0x33, 0x4b, 0x54, 0x72, 0x77, 0x4a, 0x6a, 0x6b, + 0x5a, 0x2f, 0x61, 0x53, 0x72, 0x31, 0x74, 0x79, 0x44, 0x30, 0x2f, 0x74, + 0x58, 0x76, 0x75, 0x6b, 0x52, 0x46, 0x69, 0x50, 0x78, 0x57, 0x42, 0x4a, + 0x68, 0x6a, 0x48, 0x51, 0x37, 0x30, 0x47, 0x71, 0x54, 0x0a, 0x46, 0x51, + 0x59, 0x31, 0x39, 0x52, 0x62, 0x68, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, + 0x45, 0x43, 0x67, 0x67, 0x45, 0x41, 0x49, 0x4c, 0x38, 0x4a, 0x55, 0x68, + 0x4c, 0x34, 0x61, 0x77, 0x79, 0x76, 0x70, 0x57, 0x68, 0x51, 0x38, 0x78, + 0x50, 0x67, 0x54, 0x53, 0x6c, 0x57, 0x77, 0x62, 0x45, 0x6e, 0x38, 0x42, + 0x45, 0x30, 0x54, 0x61, 0x63, 0x4a, 0x6e, 0x43, 0x49, 0x4c, 0x75, 0x68, + 0x4e, 0x4d, 0x0a, 0x42, 0x52, 0x64, 0x66, 0x38, 0x4c, 0x6c, 0x52, 0x6b, + 0x2f, 0x38, 0x50, 0x4b, 0x51, 0x77, 0x56, 0x70, 0x56, 0x46, 0x33, 0x54, + 0x46, 0x62, 0x59, 0x53, 0x4d, 0x49, 0x2b, 0x55, 0x36, 0x62, 0x34, 0x68, + 0x4d, 0x56, 0x73, 0x73, 0x66, 0x76, 0x33, 0x48, 0x56, 0x51, 0x63, 0x2f, + 0x30, 0x38, 0x33, 0x64, 0x48, 0x71, 0x2b, 0x33, 0x58, 0x4f, 0x77, 0x55, + 0x43, 0x56, 0x6c, 0x55, 0x73, 0x74, 0x52, 0x0a, 0x53, 0x41, 0x7a, 0x54, + 0x45, 0x32, 0x45, 0x35, 0x45, 0x44, 0x4d, 0x72, 0x31, 0x73, 0x74, 0x64, + 0x68, 0x30, 0x53, 0x51, 0x68, 0x56, 0x34, 0x4e, 0x69, 0x6c, 0x66, 0x6f, + 0x73, 0x39, 0x73, 0x35, 0x55, 0x6b, 0x31, 0x5a, 0x36, 0x49, 0x47, 0x53, + 0x7a, 0x74, 0x6f, 0x7a, 0x31, 0x47, 0x67, 0x4f, 0x45, 0x72, 0x49, 0x63, + 0x2f, 0x6d, 0x47, 0x50, 0x79, 0x2f, 0x61, 0x41, 0x2f, 0x68, 0x62, 0x72, + 0x0a, 0x66, 0x52, 0x57, 0x48, 0x76, 0x54, 0x70, 0x33, 0x35, 0x2b, 0x4d, + 0x62, 0x43, 0x4a, 0x53, 0x76, 0x5a, 0x75, 0x4f, 0x65, 0x65, 0x76, 0x58, + 0x32, 0x69, 0x4c, 0x73, 0x30, 0x64, 0x4e, 0x7a, 0x71, 0x64, 0x6b, 0x36, + 0x44, 0x69, 0x4f, 0x57, 0x49, 0x48, 0x2f, 0x42, 0x56, 0x47, 0x69, 0x72, + 0x56, 0x50, 0x74, 0x4f, 0x36, 0x79, 0x6b, 0x72, 0x6b, 0x75, 0x54, 0x6a, + 0x31, 0x46, 0x57, 0x69, 0x4e, 0x0a, 0x68, 0x79, 0x5a, 0x33, 0x4d, 0x42, + 0x43, 0x68, 0x53, 0x68, 0x6c, 0x4e, 0x48, 0x32, 0x70, 0x6f, 0x4e, 0x58, + 0x34, 0x36, 0x6e, 0x74, 0x4f, 0x63, 0x37, 0x6e, 0x45, 0x75, 0x73, 0x30, + 0x71, 0x74, 0x65, 0x4f, 0x67, 0x78, 0x42, 0x4b, 0x38, 0x6c, 0x75, 0x6d, + 0x6d, 0x46, 0x45, 0x74, 0x6c, 0x65, 0x68, 0x43, 0x41, 0x37, 0x68, 0x64, + 0x2f, 0x38, 0x78, 0x75, 0x76, 0x59, 0x6c, 0x50, 0x30, 0x6b, 0x0a, 0x37, + 0x61, 0x4e, 0x36, 0x38, 0x34, 0x4c, 0x43, 0x52, 0x44, 0x61, 0x6a, 0x6d, + 0x41, 0x47, 0x70, 0x6f, 0x5a, 0x4f, 0x35, 0x37, 0x4e, 0x53, 0x44, 0x59, + 0x51, 0x68, 0x41, 0x46, 0x47, 0x5a, 0x65, 0x55, 0x5a, 0x39, 0x33, 0x53, + 0x4d, 0x46, 0x75, 0x63, 0x51, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x65, 0x37, + 0x47, 0x47, 0x6b, 0x7a, 0x5a, 0x46, 0x45, 0x69, 0x76, 0x39, 0x31, 0x75, + 0x31, 0x71, 0x39, 0x0a, 0x6c, 0x67, 0x4d, 0x79, 0x31, 0x68, 0x35, 0x64, + 0x5a, 0x6a, 0x49, 0x5a, 0x4b, 0x67, 0x51, 0x61, 0x4f, 0x61, 0x72, 0x50, + 0x43, 0x36, 0x77, 0x43, 0x51, 0x4d, 0x55, 0x64, 0x71, 0x43, 0x66, 0x36, + 0x63, 0x53, 0x4c, 0x73, 0x41, 0x50, 0x72, 0x34, 0x54, 0x38, 0x45, 0x44, + 0x6f, 0x57, 0x73, 0x6e, 0x59, 0x37, 0x64, 0x53, 0x6e, 0x72, 0x54, 0x5a, + 0x36, 0x59, 0x43, 0x49, 0x46, 0x4c, 0x31, 0x54, 0x0a, 0x69, 0x64, 0x67, + 0x38, 0x4d, 0x33, 0x42, 0x51, 0x58, 0x69, 0x70, 0x49, 0x43, 0x43, 0x4a, + 0x6b, 0x46, 0x4f, 0x52, 0x53, 0x37, 0x36, 0x70, 0x4b, 0x4b, 0x5a, 0x30, + 0x77, 0x4d, 0x6e, 0x33, 0x2f, 0x4e, 0x67, 0x6b, 0x53, 0x65, 0x70, 0x73, + 0x6d, 0x4e, 0x63, 0x74, 0x39, 0x31, 0x57, 0x48, 0x72, 0x36, 0x6f, 0x6b, + 0x76, 0x78, 0x34, 0x74, 0x4f, 0x61, 0x6f, 0x52, 0x43, 0x74, 0x64, 0x7a, + 0x55, 0x0a, 0x67, 0x37, 0x6a, 0x74, 0x34, 0x4d, 0x72, 0x33, 0x73, 0x66, + 0x4c, 0x43, 0x69, 0x5a, 0x74, 0x71, 0x54, 0x51, 0x79, 0x79, 0x53, 0x64, + 0x4d, 0x55, 0x45, 0x77, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x4e, 0x4b, 0x2b, + 0x5a, 0x46, 0x4b, 0x4c, 0x30, 0x58, 0x68, 0x6b, 0x57, 0x5a, 0x50, 0x2b, + 0x50, 0x47, 0x4b, 0x6a, 0x57, 0x47, 0x38, 0x4c, 0x57, 0x70, 0x50, 0x69, + 0x4b, 0x33, 0x64, 0x37, 0x38, 0x2f, 0x0a, 0x77, 0x59, 0x42, 0x46, 0x58, + 0x7a, 0x53, 0x54, 0x47, 0x6c, 0x6b, 0x72, 0x36, 0x46, 0x76, 0x52, 0x6d, + 0x59, 0x74, 0x5a, 0x65, 0x4e, 0x77, 0x58, 0x57, 0x52, 0x59, 0x4c, 0x42, + 0x34, 0x55, 0x78, 0x5a, 0x39, 0x41, 0x74, 0x34, 0x68, 0x62, 0x4a, 0x56, + 0x45, 0x64, 0x69, 0x2f, 0x32, 0x64, 0x49, 0x54, 0x4f, 0x7a, 0x2f, 0x73, + 0x65, 0x68, 0x56, 0x44, 0x79, 0x43, 0x41, 0x6a, 0x6a, 0x73, 0x33, 0x0a, + 0x67, 0x79, 0x63, 0x73, 0x63, 0x33, 0x55, 0x4a, 0x71, 0x69, 0x5a, 0x62, + 0x63, 0x77, 0x35, 0x58, 0x4b, 0x68, 0x49, 0x35, 0x54, 0x57, 0x42, 0x75, + 0x57, 0x78, 0x6b, 0x4b, 0x45, 0x4e, 0x64, 0x62, 0x4d, 0x53, 0x61, 0x79, + 0x6f, 0x67, 0x56, 0x62, 0x70, 0x32, 0x61, 0x53, 0x59, 0x6f, 0x52, 0x62, + 0x6c, 0x48, 0x37, 0x36, 0x34, 0x2f, 0x2f, 0x74, 0x30, 0x41, 0x43, 0x6d, + 0x62, 0x66, 0x54, 0x57, 0x0a, 0x4b, 0x55, 0x51, 0x52, 0x51, 0x50, 0x42, + 0x2f, 0x75, 0x77, 0x4b, 0x42, 0x67, 0x51, 0x43, 0x35, 0x51, 0x6a, 0x6a, + 0x6a, 0x66, 0x50, 0x4c, 0x38, 0x77, 0x34, 0x63, 0x4a, 0x6b, 0x47, 0x6f, + 0x59, 0x70, 0x46, 0x4b, 0x45, 0x4c, 0x4f, 0x32, 0x50, 0x4d, 0x52, 0x37, + 0x78, 0x53, 0x72, 0x6d, 0x65, 0x45, 0x63, 0x36, 0x68, 0x77, 0x6c, 0x46, + 0x77, 0x6a, 0x65, 0x4e, 0x43, 0x67, 0x6a, 0x79, 0x33, 0x0a, 0x4a, 0x4d, + 0x36, 0x67, 0x30, 0x79, 0x2b, 0x2b, 0x72, 0x49, 0x6a, 0x37, 0x4f, 0x32, + 0x71, 0x52, 0x6b, 0x59, 0x30, 0x49, 0x58, 0x46, 0x78, 0x76, 0x76, 0x46, + 0x33, 0x55, 0x75, 0x57, 0x65, 0x64, 0x78, 0x54, 0x43, 0x75, 0x31, 0x78, + 0x43, 0x2f, 0x75, 0x59, 0x48, 0x70, 0x32, 0x74, 0x69, 0x35, 0x30, 0x36, + 0x4c, 0x73, 0x53, 0x63, 0x42, 0x37, 0x59, 0x5a, 0x6f, 0x41, 0x4d, 0x2f, + 0x59, 0x42, 0x0a, 0x34, 0x69, 0x59, 0x6e, 0x39, 0x54, 0x78, 0x36, 0x78, + 0x4c, 0x6f, 0x59, 0x47, 0x50, 0x30, 0x48, 0x30, 0x69, 0x47, 0x77, 0x55, + 0x32, 0x53, 0x79, 0x42, 0x6c, 0x4e, 0x6b, 0x48, 0x54, 0x38, 0x6f, 0x58, + 0x55, 0x2b, 0x53, 0x59, 0x50, 0x35, 0x4d, 0x57, 0x74, 0x59, 0x6b, 0x56, + 0x62, 0x65, 0x53, 0x33, 0x2f, 0x56, 0x74, 0x4e, 0x57, 0x7a, 0x31, 0x67, + 0x51, 0x4b, 0x42, 0x67, 0x51, 0x43, 0x41, 0x0a, 0x36, 0x4e, 0x6b, 0x34, + 0x6b, 0x4e, 0x30, 0x6d, 0x48, 0x37, 0x59, 0x78, 0x45, 0x4b, 0x52, 0x7a, + 0x53, 0x4f, 0x66, 0x79, 0x7a, 0x65, 0x44, 0x46, 0x34, 0x6f, 0x56, 0x37, + 0x6b, 0x75, 0x42, 0x32, 0x46, 0x59, 0x55, 0x62, 0x6b, 0x54, 0x4c, 0x2b, + 0x54, 0x69, 0x72, 0x43, 0x33, 0x4b, 0x35, 0x38, 0x4a, 0x69, 0x59, 0x59, + 0x35, 0x45, 0x67, 0x63, 0x33, 0x31, 0x74, 0x72, 0x4f, 0x4b, 0x46, 0x6d, + 0x0a, 0x4a, 0x6c, 0x7a, 0x31, 0x78, 0x7a, 0x30, 0x62, 0x36, 0x44, 0x6b, + 0x6d, 0x4b, 0x57, 0x54, 0x69, 0x56, 0x33, 0x72, 0x39, 0x4f, 0x50, 0x48, + 0x4b, 0x4a, 0x38, 0x50, 0x37, 0x49, 0x65, 0x4a, 0x78, 0x41, 0x5a, 0x57, + 0x6d, 0x5a, 0x7a, 0x43, 0x64, 0x44, 0x75, 0x77, 0x6b, 0x76, 0x30, 0x69, + 0x2b, 0x57, 0x57, 0x2b, 0x7a, 0x30, 0x7a, 0x73, 0x49, 0x65, 0x33, 0x4a, + 0x6a, 0x45, 0x61, 0x76, 0x4e, 0x0a, 0x33, 0x7a, 0x62, 0x36, 0x4f, 0x37, + 0x52, 0x30, 0x48, 0x74, 0x7a, 0x69, 0x6b, 0x73, 0x57, 0x6f, 0x71, 0x4d, + 0x65, 0x54, 0x71, 0x5a, 0x65, 0x4f, 0x2b, 0x77, 0x61, 0x39, 0x69, 0x77, + 0x36, 0x76, 0x56, 0x4b, 0x51, 0x77, 0x31, 0x77, 0x57, 0x45, 0x71, 0x77, + 0x4b, 0x42, 0x67, 0x46, 0x48, 0x66, 0x61, 0x68, 0x46, 0x73, 0x30, 0x44, + 0x5a, 0x35, 0x63, 0x55, 0x54, 0x70, 0x47, 0x70, 0x42, 0x74, 0x0a, 0x46, + 0x2f, 0x41, 0x51, 0x47, 0x37, 0x75, 0x6b, 0x67, 0x69, 0x70, 0x42, 0x36, + 0x4e, 0x36, 0x41, 0x6b, 0x42, 0x39, 0x6b, 0x44, 0x62, 0x67, 0x43, 0x73, + 0x31, 0x46, 0x4c, 0x67, 0x64, 0x31, 0x39, 0x39, 0x4d, 0x51, 0x72, 0x45, + 0x6e, 0x63, 0x75, 0x67, 0x35, 0x68, 0x66, 0x70, 0x71, 0x38, 0x51, 0x65, + 0x72, 0x62, 0x79, 0x4d, 0x61, 0x74, 0x6d, 0x41, 0x2b, 0x47, 0x58, 0x6f, + 0x47, 0x4d, 0x62, 0x0a, 0x37, 0x76, 0x7a, 0x74, 0x4b, 0x45, 0x48, 0x38, + 0x35, 0x79, 0x7a, 0x70, 0x34, 0x6e, 0x30, 0x32, 0x46, 0x4e, 0x4c, 0x36, + 0x48, 0x37, 0x78, 0x4c, 0x34, 0x56, 0x56, 0x49, 0x4c, 0x76, 0x79, 0x5a, + 0x48, 0x64, 0x6f, 0x6c, 0x6d, 0x69, 0x4f, 0x52, 0x4a, 0x34, 0x71, 0x54, + 0x32, 0x68, 0x5a, 0x6e, 0x6c, 0x38, 0x70, 0x45, 0x51, 0x32, 0x54, 0x59, + 0x75, 0x46, 0x34, 0x52, 0x6c, 0x48, 0x55, 0x64, 0x0a, 0x6e, 0x53, 0x77, + 0x58, 0x58, 0x2b, 0x32, 0x6f, 0x30, 0x4a, 0x2f, 0x6e, 0x46, 0x38, 0x35, + 0x66, 0x6d, 0x34, 0x41, 0x77, 0x57, 0x4b, 0x41, 0x63, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, + 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + 0x00}; diff --git a/test/core/end2end/data/server1_cert.cc b/test/core/end2end/data/server1_cert.cc index 0943244ecc8..b780a84d6d1 100644 --- a/test/core/end2end/data/server1_cert.cc +++ b/test/core/end2end/data/server1_cert.cc @@ -19,82 +19,114 @@ extern const char test_server1_cert[] = { 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x6e, 0x44, 0x43, 0x43, - 0x41, 0x67, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42, - 0x42, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, - 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x57, - 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, - 0x45, 0x77, 0x4a, 0x42, 0x56, 0x54, 0x45, 0x54, 0x0a, 0x4d, 0x42, 0x45, - 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, 0x4d, 0x4b, 0x55, 0x32, 0x39, - 0x74, 0x5a, 0x53, 0x31, 0x54, 0x64, 0x47, 0x46, 0x30, 0x5a, 0x54, 0x45, - 0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d, - 0x59, 0x53, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x5a, 0x58, 0x51, - 0x67, 0x56, 0x32, 0x6c, 0x6b, 0x5a, 0x32, 0x6c, 0x30, 0x63, 0x79, 0x42, - 0x51, 0x0a, 0x64, 0x48, 0x6b, 0x67, 0x54, 0x48, 0x52, 0x6b, 0x4d, 0x51, - 0x38, 0x77, 0x44, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x77, - 0x5a, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x59, 0x32, 0x45, 0x77, 0x48, 0x68, - 0x63, 0x4e, 0x4d, 0x54, 0x55, 0x78, 0x4d, 0x54, 0x41, 0x30, 0x4d, 0x44, - 0x49, 0x79, 0x4d, 0x44, 0x49, 0x30, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a, - 0x55, 0x78, 0x4d, 0x54, 0x41, 0x78, 0x0a, 0x4d, 0x44, 0x49, 0x79, 0x4d, - 0x44, 0x49, 0x30, 0x57, 0x6a, 0x42, 0x6c, 0x4d, 0x51, 0x73, 0x77, 0x43, - 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, - 0x7a, 0x45, 0x52, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, - 0x42, 0x4d, 0x49, 0x53, 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61, - 0x58, 0x4d, 0x78, 0x45, 0x44, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x0a, - 0x42, 0x41, 0x63, 0x54, 0x42, 0x30, 0x4e, 0x6f, 0x61, 0x57, 0x4e, 0x68, - 0x5a, 0x32, 0x38, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4e, 0x56, - 0x42, 0x41, 0x6f, 0x54, 0x44, 0x45, 0x56, 0x34, 0x59, 0x57, 0x31, 0x77, - 0x62, 0x47, 0x55, 0x73, 0x49, 0x45, 0x4e, 0x76, 0x4c, 0x6a, 0x45, 0x61, - 0x4d, 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x51, 0x52, - 0x4b, 0x69, 0x35, 0x30, 0x0a, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64, - 0x76, 0x62, 0x32, 0x64, 0x73, 0x5a, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x30, - 0x77, 0x67, 0x5a, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, - 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, - 0x44, 0x67, 0x59, 0x30, 0x41, 0x4d, 0x49, 0x47, 0x4a, 0x41, 0x6f, 0x47, - 0x42, 0x41, 0x4f, 0x48, 0x44, 0x46, 0x53, 0x63, 0x6f, 0x0a, 0x4c, 0x43, - 0x56, 0x4a, 0x70, 0x59, 0x44, 0x44, 0x4d, 0x34, 0x48, 0x59, 0x74, 0x49, - 0x64, 0x56, 0x36, 0x41, 0x6b, 0x65, 0x2f, 0x73, 0x4d, 0x4e, 0x61, 0x61, - 0x4b, 0x64, 0x4f, 0x44, 0x6a, 0x44, 0x4d, 0x73, 0x75, 0x78, 0x2f, 0x34, - 0x74, 0x44, 0x79, 0x64, 0x6c, 0x75, 0x6d, 0x4e, 0x2b, 0x66, 0x6d, 0x2b, - 0x41, 0x6a, 0x50, 0x45, 0x4b, 0x35, 0x47, 0x48, 0x68, 0x47, 0x6e, 0x31, - 0x42, 0x67, 0x0a, 0x7a, 0x6b, 0x57, 0x46, 0x2b, 0x73, 0x6c, 0x66, 0x33, - 0x42, 0x78, 0x68, 0x72, 0x41, 0x2f, 0x38, 0x64, 0x4e, 0x73, 0x6e, 0x75, - 0x6e, 0x73, 0x74, 0x56, 0x41, 0x37, 0x5a, 0x42, 0x67, 0x41, 0x2f, 0x35, - 0x71, 0x51, 0x78, 0x4d, 0x66, 0x47, 0x41, 0x71, 0x34, 0x77, 0x48, 0x4e, - 0x56, 0x58, 0x37, 0x37, 0x66, 0x42, 0x5a, 0x4f, 0x67, 0x70, 0x39, 0x56, - 0x6c, 0x53, 0x4d, 0x56, 0x66, 0x79, 0x64, 0x0a, 0x39, 0x4e, 0x38, 0x59, - 0x77, 0x62, 0x42, 0x59, 0x41, 0x63, 0x6b, 0x4f, 0x65, 0x55, 0x51, 0x61, - 0x64, 0x54, 0x69, 0x32, 0x58, 0x31, 0x53, 0x36, 0x4f, 0x67, 0x4a, 0x58, - 0x67, 0x51, 0x30, 0x6d, 0x33, 0x4d, 0x57, 0x68, 0x41, 0x67, 0x4d, 0x42, - 0x41, 0x41, 0x47, 0x6a, 0x61, 0x7a, 0x42, 0x70, 0x4d, 0x41, 0x6b, 0x47, - 0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x51, 0x43, 0x4d, 0x41, 0x41, 0x77, - 0x0a, 0x43, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x42, 0x41, 0x51, - 0x44, 0x41, 0x67, 0x58, 0x67, 0x4d, 0x45, 0x38, 0x47, 0x41, 0x31, 0x55, - 0x64, 0x45, 0x51, 0x52, 0x49, 0x4d, 0x45, 0x61, 0x43, 0x45, 0x43, 0x6f, + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x74, 0x44, 0x43, 0x43, + 0x41, 0x70, 0x79, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, + 0x62, 0x4a, 0x66, 0x54, 0x52, 0x45, 0x4a, 0x36, 0x6b, 0x36, 0x2f, 0x2b, + 0x6f, 0x49, 0x6e, 0x57, 0x68, 0x56, 0x31, 0x4f, 0x31, 0x6a, 0x33, 0x5a, + 0x54, 0x30, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, + 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41, + 0x77, 0x56, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, + 0x45, 0x42, 0x68, 0x4d, 0x43, 0x51, 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, + 0x52, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, + 0x76, 0x62, 0x57, 0x55, 0x74, 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, + 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, + 0x4d, 0x0a, 0x47, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, + 0x56, 0x30, 0x49, 0x46, 0x64, 0x70, 0x5a, 0x47, 0x64, 0x70, 0x64, 0x48, + 0x4d, 0x67, 0x55, 0x48, 0x52, 0x35, 0x49, 0x45, 0x78, 0x30, 0x5a, 0x44, + 0x45, 0x50, 0x4d, 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, + 0x77, 0x47, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x47, 0x4e, 0x68, 0x4d, 0x42, + 0x34, 0x58, 0x44, 0x54, 0x49, 0x77, 0x0a, 0x4d, 0x44, 0x4d, 0x78, 0x4f, + 0x44, 0x41, 0x7a, 0x4d, 0x54, 0x41, 0x30, 0x4d, 0x6c, 0x6f, 0x58, 0x44, + 0x54, 0x4d, 0x77, 0x4d, 0x44, 0x4d, 0x78, 0x4e, 0x6a, 0x41, 0x7a, 0x4d, + 0x54, 0x41, 0x30, 0x4d, 0x6c, 0x6f, 0x77, 0x5a, 0x54, 0x45, 0x4c, 0x4d, + 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, + 0x56, 0x4d, 0x78, 0x45, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x0a, + 0x42, 0x41, 0x67, 0x4d, 0x43, 0x45, 0x6c, 0x73, 0x62, 0x47, 0x6c, 0x75, + 0x62, 0x32, 0x6c, 0x7a, 0x4d, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, + 0x56, 0x51, 0x51, 0x48, 0x44, 0x41, 0x64, 0x44, 0x61, 0x47, 0x6c, 0x6a, + 0x59, 0x57, 0x64, 0x76, 0x4d, 0x52, 0x55, 0x77, 0x45, 0x77, 0x59, 0x44, + 0x56, 0x51, 0x51, 0x4b, 0x44, 0x41, 0x78, 0x46, 0x65, 0x47, 0x46, 0x74, + 0x63, 0x47, 0x78, 0x6c, 0x0a, 0x4c, 0x43, 0x42, 0x44, 0x62, 0x79, 0x34, + 0x78, 0x47, 0x6a, 0x41, 0x59, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, + 0x4d, 0x45, 0x53, 0x6f, 0x75, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x43, 0x35, + 0x6e, 0x62, 0x32, 0x39, 0x6e, 0x62, 0x47, 0x55, 0x75, 0x59, 0x32, 0x39, + 0x74, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, + 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x0a, 0x41, 0x51, + 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, + 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x35, 0x78, + 0x4f, 0x4f, 0x4e, 0x78, 0x4a, 0x4a, 0x38, 0x62, 0x38, 0x51, 0x61, 0x75, + 0x76, 0x6f, 0x62, 0x35, 0x2f, 0x37, 0x64, 0x50, 0x59, 0x5a, 0x66, 0x49, + 0x63, 0x64, 0x2b, 0x75, 0x68, 0x41, 0x57, 0x4c, 0x32, 0x5a, 0x6c, 0x54, + 0x50, 0x7a, 0x0a, 0x51, 0x76, 0x75, 0x34, 0x6f, 0x46, 0x30, 0x51, 0x49, + 0x34, 0x69, 0x59, 0x67, 0x50, 0x35, 0x69, 0x47, 0x67, 0x72, 0x79, 0x39, + 0x7a, 0x45, 0x74, 0x43, 0x4d, 0x2b, 0x59, 0x51, 0x53, 0x38, 0x55, 0x68, + 0x69, 0x41, 0x6c, 0x50, 0x6c, 0x71, 0x61, 0x36, 0x41, 0x4e, 0x78, 0x67, + 0x69, 0x42, 0x53, 0x45, 0x79, 0x4d, 0x48, 0x48, 0x2f, 0x78, 0x45, 0x38, + 0x6c, 0x6f, 0x2f, 0x2b, 0x63, 0x61, 0x59, 0x0a, 0x47, 0x65, 0x41, 0x43, + 0x71, 0x79, 0x36, 0x34, 0x30, 0x4a, 0x70, 0x6c, 0x2f, 0x4a, 0x6f, 0x63, + 0x46, 0x47, 0x6f, 0x33, 0x78, 0x64, 0x31, 0x4c, 0x38, 0x44, 0x43, 0x61, + 0x77, 0x6a, 0x6c, 0x61, 0x6a, 0x36, 0x65, 0x75, 0x37, 0x54, 0x37, 0x54, + 0x2f, 0x74, 0x70, 0x41, 0x56, 0x32, 0x71, 0x71, 0x31, 0x33, 0x62, 0x35, + 0x37, 0x31, 0x30, 0x65, 0x4e, 0x52, 0x62, 0x43, 0x41, 0x66, 0x46, 0x65, + 0x0a, 0x38, 0x79, 0x41, 0x4c, 0x69, 0x47, 0x51, 0x65, 0x6d, 0x78, 0x30, + 0x49, 0x59, 0x68, 0x6c, 0x5a, 0x58, 0x4e, 0x62, 0x49, 0x47, 0x57, 0x4c, + 0x42, 0x4e, 0x68, 0x42, 0x68, 0x76, 0x56, 0x6a, 0x4a, 0x68, 0x37, 0x55, + 0x76, 0x4f, 0x71, 0x70, 0x41, 0x44, 0x6b, 0x34, 0x78, 0x74, 0x6c, 0x38, + 0x6f, 0x35, 0x6a, 0x30, 0x78, 0x67, 0x4d, 0x49, 0x52, 0x67, 0x36, 0x57, + 0x4a, 0x47, 0x4b, 0x36, 0x63, 0x0a, 0x36, 0x66, 0x66, 0x53, 0x49, 0x67, + 0x34, 0x65, 0x50, 0x31, 0x58, 0x6d, 0x6f, 0x76, 0x4e, 0x59, 0x5a, 0x39, + 0x4c, 0x4c, 0x45, 0x4a, 0x47, 0x36, 0x38, 0x74, 0x46, 0x30, 0x51, 0x2f, + 0x79, 0x49, 0x4e, 0x34, 0x33, 0x42, 0x34, 0x64, 0x74, 0x31, 0x6f, 0x71, + 0x34, 0x6a, 0x7a, 0x53, 0x64, 0x43, 0x62, 0x47, 0x34, 0x46, 0x31, 0x45, + 0x69, 0x79, 0x6b, 0x54, 0x32, 0x54, 0x6d, 0x77, 0x50, 0x56, 0x0a, 0x59, + 0x44, 0x69, 0x38, 0x74, 0x6d, 0x6c, 0x36, 0x44, 0x66, 0x4f, 0x43, 0x44, + 0x47, 0x6e, 0x69, 0x74, 0x38, 0x73, 0x76, 0x6e, 0x4d, 0x45, 0x6d, 0x42, + 0x76, 0x2f, 0x66, 0x63, 0x50, 0x64, 0x33, 0x31, 0x47, 0x53, 0x62, 0x58, + 0x6a, 0x46, 0x38, 0x4d, 0x2b, 0x4b, 0x47, 0x47, 0x51, 0x49, 0x44, 0x41, + 0x51, 0x41, 0x42, 0x6f, 0x32, 0x73, 0x77, 0x61, 0x54, 0x41, 0x4a, 0x42, + 0x67, 0x4e, 0x56, 0x0a, 0x48, 0x52, 0x4d, 0x45, 0x41, 0x6a, 0x41, 0x41, + 0x4d, 0x41, 0x73, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, 0x77, 0x51, 0x45, + 0x41, 0x77, 0x49, 0x46, 0x34, 0x44, 0x42, 0x50, 0x42, 0x67, 0x4e, 0x56, + 0x48, 0x52, 0x45, 0x45, 0x53, 0x44, 0x42, 0x47, 0x67, 0x68, 0x41, 0x71, + 0x4c, 0x6e, 0x52, 0x6c, 0x63, 0x33, 0x51, 0x75, 0x5a, 0x32, 0x39, 0x76, + 0x5a, 0x32, 0x78, 0x6c, 0x4c, 0x6d, 0x5a, 0x79, 0x0a, 0x67, 0x68, 0x68, + 0x33, 0x59, 0x58, 0x52, 0x6c, 0x63, 0x6e, 0x70, 0x76, 0x62, 0x32, 0x6b, 0x75, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x6e, 0x62, 0x32, 0x39, - 0x6e, 0x62, 0x47, 0x55, 0x75, 0x5a, 0x6e, 0x4b, 0x43, 0x47, 0x48, 0x64, - 0x68, 0x64, 0x47, 0x56, 0x79, 0x0a, 0x65, 0x6d, 0x39, 0x76, 0x61, 0x53, - 0x35, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64, 0x76, 0x62, 0x32, - 0x64, 0x73, 0x5a, 0x53, 0x35, 0x69, 0x5a, 0x59, 0x49, 0x53, 0x4b, 0x69, - 0x35, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x6c, 0x76, 0x64, 0x58, - 0x52, 0x31, 0x59, 0x6d, 0x55, 0x75, 0x59, 0x32, 0x39, 0x74, 0x68, 0x77, - 0x54, 0x41, 0x71, 0x41, 0x45, 0x44, 0x4d, 0x41, 0x30, 0x47, 0x0a, 0x43, - 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, - 0x77, 0x55, 0x41, 0x41, 0x34, 0x47, 0x42, 0x41, 0x4a, 0x46, 0x58, 0x56, - 0x69, 0x66, 0x51, 0x4e, 0x75, 0x62, 0x31, 0x4c, 0x55, 0x50, 0x34, 0x4a, - 0x6c, 0x6e, 0x58, 0x35, 0x6c, 0x58, 0x4e, 0x6c, 0x6f, 0x38, 0x46, 0x78, - 0x5a, 0x32, 0x61, 0x31, 0x32, 0x41, 0x46, 0x51, 0x73, 0x2b, 0x62, 0x7a, - 0x6f, 0x4a, 0x36, 0x0a, 0x68, 0x4d, 0x30, 0x34, 0x34, 0x45, 0x44, 0x6a, - 0x71, 0x79, 0x78, 0x55, 0x71, 0x53, 0x62, 0x56, 0x65, 0x50, 0x4b, 0x30, - 0x6e, 0x69, 0x33, 0x77, 0x31, 0x66, 0x48, 0x51, 0x42, 0x35, 0x72, 0x59, - 0x39, 0x79, 0x59, 0x43, 0x35, 0x66, 0x38, 0x47, 0x37, 0x61, 0x71, 0x71, - 0x54, 0x59, 0x31, 0x51, 0x4f, 0x68, 0x6f, 0x55, 0x6b, 0x38, 0x5a, 0x54, - 0x53, 0x54, 0x52, 0x70, 0x6e, 0x6b, 0x54, 0x68, 0x0a, 0x79, 0x34, 0x6a, - 0x6a, 0x64, 0x76, 0x54, 0x5a, 0x65, 0x4c, 0x44, 0x56, 0x42, 0x6c, 0x75, - 0x65, 0x5a, 0x55, 0x54, 0x44, 0x52, 0x6d, 0x79, 0x32, 0x66, 0x65, 0x59, - 0x35, 0x61, 0x5a, 0x49, 0x55, 0x31, 0x38, 0x76, 0x46, 0x44, 0x4b, 0x30, - 0x38, 0x64, 0x54, 0x47, 0x30, 0x41, 0x38, 0x37, 0x70, 0x70, 0x70, 0x75, - 0x76, 0x31, 0x4c, 0x4e, 0x49, 0x52, 0x33, 0x6c, 0x6f, 0x76, 0x65, 0x55, - 0x38, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, - 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; + 0x6e, 0x62, 0x47, 0x55, 0x75, 0x59, 0x6d, 0x57, 0x43, 0x45, 0x69, 0x6f, + 0x75, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x35, 0x62, 0x33, 0x56, + 0x30, 0x64, 0x57, 0x4a, 0x6c, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x59, 0x63, + 0x45, 0x0a, 0x77, 0x4b, 0x67, 0x42, 0x41, 0x7a, 0x41, 0x4e, 0x42, 0x67, + 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, + 0x73, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x53, 0x38, + 0x68, 0x44, 0x51, 0x41, 0x38, 0x50, 0x53, 0x67, 0x69, 0x70, 0x67, 0x41, + 0x6d, 0x6c, 0x37, 0x51, 0x33, 0x2f, 0x64, 0x6a, 0x77, 0x51, 0x36, 0x34, + 0x34, 0x67, 0x68, 0x57, 0x51, 0x76, 0x0a, 0x43, 0x32, 0x4b, 0x62, 0x2b, + 0x72, 0x33, 0x30, 0x52, 0x43, 0x59, 0x31, 0x45, 0x79, 0x4b, 0x4e, 0x68, + 0x6e, 0x51, 0x6e, 0x49, 0x49, 0x68, 0x2f, 0x4f, 0x55, 0x62, 0x42, 0x5a, + 0x76, 0x68, 0x30, 0x4d, 0x30, 0x69, 0x59, 0x73, 0x79, 0x36, 0x78, 0x71, + 0x58, 0x67, 0x66, 0x44, 0x68, 0x43, 0x42, 0x39, 0x33, 0x41, 0x41, 0x36, + 0x6a, 0x30, 0x69, 0x35, 0x63, 0x53, 0x38, 0x66, 0x6b, 0x68, 0x48, 0x0a, + 0x4a, 0x6c, 0x34, 0x52, 0x4b, 0x30, 0x74, 0x53, 0x6b, 0x47, 0x51, 0x33, + 0x59, 0x4e, 0x59, 0x34, 0x4e, 0x7a, 0x58, 0x77, 0x51, 0x50, 0x2f, 0x76, + 0x6d, 0x55, 0x67, 0x66, 0x6b, 0x77, 0x38, 0x56, 0x42, 0x41, 0x5a, 0x34, + 0x59, 0x34, 0x47, 0x4b, 0x78, 0x70, 0x70, 0x64, 0x41, 0x54, 0x6a, 0x66, + 0x66, 0x49, 0x57, 0x2b, 0x73, 0x72, 0x62, 0x41, 0x6d, 0x64, 0x44, 0x72, + 0x75, 0x49, 0x52, 0x4d, 0x0a, 0x77, 0x50, 0x65, 0x69, 0x6b, 0x67, 0x4f, + 0x6f, 0x52, 0x72, 0x58, 0x66, 0x30, 0x4c, 0x41, 0x31, 0x66, 0x69, 0x34, + 0x54, 0x71, 0x78, 0x41, 0x52, 0x7a, 0x65, 0x52, 0x77, 0x65, 0x6e, 0x51, + 0x70, 0x61, 0x79, 0x4e, 0x66, 0x47, 0x48, 0x54, 0x76, 0x56, 0x46, 0x39, + 0x61, 0x4a, 0x6b, 0x6c, 0x38, 0x48, 0x6f, 0x61, 0x4d, 0x75, 0x6e, 0x54, + 0x41, 0x64, 0x47, 0x35, 0x70, 0x49, 0x56, 0x63, 0x72, 0x0a, 0x39, 0x47, + 0x4b, 0x69, 0x2f, 0x67, 0x45, 0x4d, 0x70, 0x58, 0x55, 0x4a, 0x62, 0x62, + 0x56, 0x76, 0x33, 0x55, 0x35, 0x66, 0x72, 0x58, 0x31, 0x57, 0x6f, 0x34, + 0x43, 0x46, 0x6f, 0x2b, 0x72, 0x5a, 0x57, 0x4a, 0x2f, 0x4c, 0x79, 0x43, + 0x4d, 0x65, 0x62, 0x30, 0x6a, 0x63, 0x69, 0x4e, 0x4c, 0x78, 0x53, 0x64, + 0x4d, 0x77, 0x6a, 0x2f, 0x45, 0x2f, 0x5a, 0x75, 0x45, 0x78, 0x6c, 0x79, + 0x65, 0x5a, 0x0a, 0x67, 0x63, 0x39, 0x63, 0x74, 0x50, 0x6a, 0x53, 0x4d, + 0x76, 0x67, 0x53, 0x79, 0x58, 0x45, 0x4b, 0x76, 0x36, 0x56, 0x77, 0x6f, + 0x62, 0x6c, 0x65, 0x65, 0x67, 0x38, 0x38, 0x56, 0x32, 0x5a, 0x67, 0x7a, + 0x65, 0x6e, 0x7a, 0x69, 0x4f, 0x52, 0x6f, 0x57, 0x6a, 0x34, 0x4b, 0x73, + 0x7a, 0x47, 0x2f, 0x6c, 0x62, 0x51, 0x5a, 0x76, 0x67, 0x3d, 0x3d, 0x0a, + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, + 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, + 0x2d, 0x0a, 0x00}; diff --git a/test/core/end2end/data/server1_key.cc b/test/core/end2end/data/server1_key.cc index 8f3ad15c266..c2b09d20d9a 100644 --- a/test/core/end2end/data/server1_key.cc +++ b/test/core/end2end/data/server1_key.cc @@ -17,77 +17,146 @@ */ extern const char test_server1_key[] = { - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x52, - 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, - 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, - 0x57, 0x77, 0x49, 0x42, 0x41, 0x41, 0x4b, 0x42, 0x67, 0x51, 0x44, 0x68, - 0x77, 0x78, 0x55, 0x6e, 0x4b, 0x43, 0x77, 0x6c, 0x53, 0x61, 0x57, 0x41, - 0x77, 0x7a, 0x4f, 0x42, 0x32, 0x4c, 0x53, 0x48, 0x56, 0x65, 0x67, 0x4a, - 0x48, 0x76, 0x37, 0x44, 0x44, 0x57, 0x6d, 0x69, 0x6e, 0x54, 0x67, 0x34, - 0x77, 0x7a, 0x4c, 0x4c, 0x73, 0x66, 0x2b, 0x4c, 0x51, 0x38, 0x6e, 0x5a, - 0x0a, 0x62, 0x70, 0x6a, 0x66, 0x6e, 0x35, 0x76, 0x67, 0x49, 0x7a, 0x78, - 0x43, 0x75, 0x52, 0x68, 0x34, 0x52, 0x70, 0x39, 0x51, 0x59, 0x4d, 0x35, - 0x46, 0x68, 0x66, 0x72, 0x4a, 0x58, 0x39, 0x77, 0x63, 0x59, 0x61, 0x77, - 0x50, 0x2f, 0x48, 0x54, 0x62, 0x4a, 0x37, 0x70, 0x37, 0x4c, 0x56, 0x51, - 0x4f, 0x32, 0x51, 0x59, 0x41, 0x50, 0x2b, 0x61, 0x6b, 0x4d, 0x54, 0x48, - 0x78, 0x67, 0x4b, 0x75, 0x4d, 0x0a, 0x42, 0x7a, 0x56, 0x56, 0x2b, 0x2b, - 0x33, 0x77, 0x57, 0x54, 0x6f, 0x4b, 0x66, 0x56, 0x5a, 0x55, 0x6a, 0x46, - 0x58, 0x38, 0x6e, 0x66, 0x54, 0x66, 0x47, 0x4d, 0x47, 0x77, 0x57, 0x41, - 0x48, 0x4a, 0x44, 0x6e, 0x6c, 0x45, 0x47, 0x6e, 0x55, 0x34, 0x74, 0x6c, - 0x39, 0x55, 0x75, 0x6a, 0x6f, 0x43, 0x56, 0x34, 0x45, 0x4e, 0x4a, 0x74, - 0x7a, 0x46, 0x6f, 0x51, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x0a, 0x41, - 0x6f, 0x47, 0x41, 0x4a, 0x2b, 0x36, 0x68, 0x70, 0x7a, 0x4e, 0x72, 0x32, - 0x34, 0x79, 0x54, 0x51, 0x5a, 0x74, 0x46, 0x57, 0x51, 0x70, 0x44, 0x70, - 0x45, 0x79, 0x46, 0x70, 0x6c, 0x64, 0x64, 0x4b, 0x4a, 0x4d, 0x4f, 0x78, - 0x44, 0x79, 0x61, 0x33, 0x53, 0x39, 0x70, 0x70, 0x4b, 0x33, 0x76, 0x54, - 0x57, 0x72, 0x49, 0x49, 0x54, 0x56, 0x32, 0x78, 0x4e, 0x63, 0x75, 0x63, - 0x77, 0x37, 0x49, 0x0a, 0x63, 0x65, 0x54, 0x62, 0x64, 0x79, 0x72, 0x47, - 0x73, 0x79, 0x6a, 0x73, 0x55, 0x30, 0x2f, 0x48, 0x64, 0x43, 0x63, 0x49, - 0x66, 0x39, 0x79, 0x6d, 0x32, 0x6a, 0x66, 0x6d, 0x47, 0x4c, 0x55, 0x77, - 0x6d, 0x79, 0x68, 0x6c, 0x74, 0x4b, 0x56, 0x77, 0x30, 0x51, 0x59, 0x63, - 0x46, 0x42, 0x30, 0x58, 0x4c, 0x6b, 0x63, 0x30, 0x6e, 0x49, 0x35, 0x59, - 0x76, 0x45, 0x59, 0x6f, 0x65, 0x56, 0x44, 0x67, 0x0a, 0x6f, 0x6d, 0x5a, - 0x49, 0x58, 0x6e, 0x31, 0x45, 0x33, 0x45, 0x57, 0x2b, 0x73, 0x53, 0x49, - 0x57, 0x53, 0x62, 0x6b, 0x4d, 0x75, 0x39, 0x62, 0x59, 0x32, 0x6b, 0x73, - 0x74, 0x4b, 0x58, 0x52, 0x32, 0x55, 0x5a, 0x6d, 0x4d, 0x67, 0x57, 0x44, - 0x74, 0x6d, 0x42, 0x45, 0x50, 0x4d, 0x61, 0x45, 0x43, 0x51, 0x51, 0x44, - 0x36, 0x79, 0x54, 0x34, 0x54, 0x41, 0x5a, 0x4d, 0x35, 0x68, 0x47, 0x42, - 0x62, 0x0a, 0x63, 0x69, 0x42, 0x4b, 0x67, 0x4d, 0x55, 0x50, 0x36, 0x50, - 0x77, 0x4f, 0x68, 0x50, 0x68, 0x4f, 0x4d, 0x50, 0x49, 0x76, 0x69, 0x6a, - 0x4f, 0x35, 0x30, 0x41, 0x69, 0x75, 0x36, 0x69, 0x75, 0x43, 0x56, 0x38, - 0x38, 0x6c, 0x31, 0x51, 0x49, 0x79, 0x33, 0x38, 0x67, 0x57, 0x56, 0x68, - 0x78, 0x6a, 0x4e, 0x72, 0x71, 0x36, 0x50, 0x33, 0x34, 0x36, 0x6a, 0x34, - 0x49, 0x42, 0x67, 0x2b, 0x6b, 0x42, 0x0a, 0x39, 0x61, 0x6c, 0x77, 0x70, - 0x43, 0x4f, 0x44, 0x41, 0x6b, 0x45, 0x41, 0x35, 0x6e, 0x53, 0x6e, 0x6d, - 0x39, 0x6b, 0x36, 0x79, 0x6b, 0x59, 0x65, 0x51, 0x57, 0x4e, 0x53, 0x30, - 0x66, 0x4e, 0x57, 0x69, 0x52, 0x69, 0x6e, 0x43, 0x64, 0x6c, 0x32, 0x33, - 0x41, 0x37, 0x75, 0x73, 0x44, 0x47, 0x53, 0x75, 0x4b, 0x4b, 0x6c, 0x6d, - 0x30, 0x31, 0x39, 0x69, 0x6f, 0x6d, 0x4a, 0x2f, 0x52, 0x67, 0x64, 0x0a, - 0x4d, 0x4b, 0x44, 0x4f, 0x70, 0x30, 0x71, 0x2f, 0x32, 0x4f, 0x6f, 0x73, - 0x74, 0x62, 0x74, 0x65, 0x4f, 0x57, 0x4d, 0x32, 0x4d, 0x52, 0x46, 0x66, - 0x34, 0x6a, 0x4d, 0x48, 0x33, 0x77, 0x79, 0x56, 0x43, 0x77, 0x4a, 0x41, - 0x66, 0x41, 0x64, 0x6a, 0x4a, 0x38, 0x73, 0x7a, 0x6f, 0x4e, 0x4b, 0x54, - 0x52, 0x53, 0x61, 0x67, 0x53, 0x62, 0x68, 0x39, 0x76, 0x57, 0x79, 0x67, - 0x6e, 0x42, 0x32, 0x76, 0x0a, 0x49, 0x42, 0x79, 0x63, 0x36, 0x6c, 0x34, - 0x54, 0x54, 0x75, 0x5a, 0x51, 0x4a, 0x52, 0x47, 0x7a, 0x43, 0x76, 0x65, - 0x61, 0x66, 0x7a, 0x39, 0x6c, 0x6f, 0x76, 0x75, 0x42, 0x33, 0x57, 0x6f, - 0x68, 0x43, 0x41, 0x42, 0x64, 0x51, 0x52, 0x64, 0x39, 0x75, 0x6b, 0x43, - 0x58, 0x4c, 0x32, 0x43, 0x70, 0x73, 0x45, 0x70, 0x71, 0x7a, 0x6b, 0x61, - 0x66, 0x4f, 0x51, 0x4a, 0x41, 0x4a, 0x55, 0x6a, 0x63, 0x0a, 0x55, 0x53, - 0x65, 0x64, 0x44, 0x6c, 0x71, 0x33, 0x7a, 0x47, 0x5a, 0x77, 0x59, 0x4d, - 0x31, 0x59, 0x77, 0x38, 0x64, 0x38, 0x52, 0x75, 0x69, 0x72, 0x42, 0x55, - 0x46, 0x5a, 0x4e, 0x71, 0x4a, 0x65, 0x6c, 0x59, 0x61, 0x69, 0x2b, 0x6e, - 0x52, 0x59, 0x43, 0x6c, 0x44, 0x6b, 0x52, 0x56, 0x46, 0x67, 0x62, 0x35, - 0x79, 0x6b, 0x73, 0x6f, 0x59, 0x79, 0x63, 0x62, 0x71, 0x35, 0x54, 0x78, - 0x47, 0x6f, 0x0a, 0x56, 0x65, 0x71, 0x4b, 0x4f, 0x76, 0x67, 0x50, 0x70, - 0x6a, 0x34, 0x52, 0x57, 0x50, 0x48, 0x6c, 0x4c, 0x77, 0x4a, 0x41, 0x47, - 0x55, 0x4d, 0x6b, 0x33, 0x62, 0x71, 0x54, 0x39, 0x31, 0x78, 0x42, 0x55, - 0x43, 0x6e, 0x4c, 0x52, 0x73, 0x2f, 0x76, 0x66, 0x6f, 0x43, 0x70, 0x48, - 0x70, 0x67, 0x36, 0x65, 0x79, 0x77, 0x51, 0x54, 0x42, 0x44, 0x41, 0x56, - 0x36, 0x78, 0x6b, 0x79, 0x7a, 0x34, 0x61, 0x0a, 0x52, 0x48, 0x33, 0x49, - 0x37, 0x2f, 0x2b, 0x79, 0x6a, 0x33, 0x5a, 0x78, 0x52, 0x32, 0x4a, 0x6f, - 0x57, 0x48, 0x67, 0x55, 0x77, 0x5a, 0x37, 0x6c, 0x5a, 0x6b, 0x31, 0x56, - 0x6e, 0x68, 0x66, 0x66, 0x46, 0x79, 0x65, 0x37, 0x53, 0x42, 0x58, 0x79, - 0x61, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, - 0x44, 0x20, 0x52, 0x53, 0x41, 0x20, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, - 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; + 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x45, 0x76, 0x77, 0x49, 0x42, + 0x41, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, + 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x53, 0x43, + 0x42, 0x4b, 0x6b, 0x77, 0x67, 0x67, 0x53, 0x6c, 0x41, 0x67, 0x45, 0x41, + 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x6e, 0x45, 0x34, 0x34, 0x33, + 0x45, 0x6b, 0x6e, 0x78, 0x76, 0x78, 0x42, 0x71, 0x0a, 0x36, 0x2b, 0x68, + 0x76, 0x6e, 0x2f, 0x74, 0x30, 0x39, 0x68, 0x6c, 0x38, 0x68, 0x78, 0x33, + 0x36, 0x36, 0x45, 0x42, 0x59, 0x76, 0x5a, 0x6d, 0x56, 0x4d, 0x2f, 0x4e, + 0x43, 0x2b, 0x37, 0x69, 0x67, 0x58, 0x52, 0x41, 0x6a, 0x69, 0x4a, 0x69, + 0x41, 0x2f, 0x6d, 0x49, 0x61, 0x43, 0x76, 0x4c, 0x33, 0x4d, 0x53, 0x30, + 0x49, 0x7a, 0x35, 0x68, 0x42, 0x4c, 0x78, 0x53, 0x47, 0x49, 0x43, 0x55, + 0x2b, 0x0a, 0x57, 0x70, 0x72, 0x6f, 0x41, 0x33, 0x47, 0x43, 0x49, 0x46, + 0x49, 0x54, 0x49, 0x77, 0x63, 0x66, 0x2f, 0x45, 0x54, 0x79, 0x57, 0x6a, + 0x2f, 0x35, 0x78, 0x70, 0x67, 0x5a, 0x34, 0x41, 0x4b, 0x72, 0x4c, 0x72, + 0x6a, 0x51, 0x6d, 0x6d, 0x58, 0x38, 0x6d, 0x68, 0x77, 0x55, 0x61, 0x6a, + 0x66, 0x46, 0x33, 0x55, 0x76, 0x77, 0x4d, 0x4a, 0x72, 0x43, 0x4f, 0x56, + 0x71, 0x50, 0x70, 0x36, 0x37, 0x74, 0x0a, 0x50, 0x74, 0x50, 0x2b, 0x32, + 0x6b, 0x42, 0x58, 0x61, 0x71, 0x72, 0x58, 0x64, 0x76, 0x6e, 0x76, 0x58, + 0x52, 0x34, 0x31, 0x46, 0x73, 0x49, 0x42, 0x38, 0x56, 0x37, 0x7a, 0x49, + 0x41, 0x75, 0x49, 0x5a, 0x42, 0x36, 0x62, 0x48, 0x51, 0x68, 0x69, 0x47, + 0x56, 0x6c, 0x63, 0x31, 0x73, 0x67, 0x5a, 0x59, 0x73, 0x45, 0x32, 0x45, + 0x47, 0x47, 0x39, 0x57, 0x4d, 0x6d, 0x48, 0x74, 0x53, 0x38, 0x36, 0x0a, + 0x71, 0x6b, 0x41, 0x4f, 0x54, 0x6a, 0x47, 0x32, 0x58, 0x79, 0x6a, 0x6d, + 0x50, 0x54, 0x47, 0x41, 0x77, 0x68, 0x47, 0x44, 0x70, 0x59, 0x6b, 0x59, + 0x72, 0x70, 0x7a, 0x70, 0x39, 0x39, 0x49, 0x69, 0x44, 0x68, 0x34, 0x2f, + 0x56, 0x65, 0x61, 0x69, 0x38, 0x31, 0x68, 0x6e, 0x30, 0x73, 0x73, 0x51, + 0x6b, 0x62, 0x72, 0x79, 0x30, 0x58, 0x52, 0x44, 0x2f, 0x49, 0x67, 0x33, + 0x6a, 0x63, 0x48, 0x68, 0x0a, 0x32, 0x33, 0x57, 0x69, 0x72, 0x69, 0x50, + 0x4e, 0x4a, 0x30, 0x4a, 0x73, 0x62, 0x67, 0x58, 0x55, 0x53, 0x4c, 0x4b, + 0x52, 0x50, 0x5a, 0x4f, 0x62, 0x41, 0x39, 0x56, 0x67, 0x4f, 0x4c, 0x79, + 0x32, 0x61, 0x58, 0x6f, 0x4e, 0x38, 0x34, 0x49, 0x4d, 0x61, 0x65, 0x4b, + 0x33, 0x79, 0x79, 0x2b, 0x63, 0x77, 0x53, 0x59, 0x47, 0x2f, 0x39, 0x39, + 0x77, 0x39, 0x33, 0x66, 0x55, 0x5a, 0x4a, 0x74, 0x65, 0x0a, 0x4d, 0x58, + 0x77, 0x7a, 0x34, 0x6f, 0x59, 0x5a, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, + 0x45, 0x43, 0x67, 0x67, 0x45, 0x42, 0x41, 0x49, 0x56, 0x6e, 0x32, 0x4e, + 0x63, 0x61, 0x69, 0x2b, 0x34, 0x78, 0x62, 0x48, 0x30, 0x4f, 0x4c, 0x57, + 0x63, 0x6b, 0x61, 0x62, 0x77, 0x67, 0x79, 0x4a, 0x34, 0x49, 0x4d, 0x39, + 0x72, 0x44, 0x63, 0x30, 0x4c, 0x49, 0x55, 0x33, 0x36, 0x38, 0x4f, 0x31, + 0x6b, 0x55, 0x0a, 0x6b, 0x6f, 0x61, 0x69, 0x73, 0x38, 0x71, 0x50, 0x39, + 0x64, 0x75, 0x6a, 0x41, 0x57, 0x67, 0x66, 0x6f, 0x68, 0x33, 0x73, 0x47, + 0x68, 0x2f, 0x59, 0x47, 0x67, 0x4b, 0x6e, 0x39, 0x36, 0x56, 0x6e, 0x73, + 0x5a, 0x6a, 0x4b, 0x48, 0x6c, 0x79, 0x4d, 0x67, 0x46, 0x2b, 0x72, 0x34, + 0x54, 0x61, 0x44, 0x4a, 0x6e, 0x33, 0x6b, 0x32, 0x72, 0x6c, 0x41, 0x4f, + 0x57, 0x63, 0x75, 0x72, 0x47, 0x6c, 0x6a, 0x0a, 0x31, 0x71, 0x61, 0x56, + 0x6c, 0x73, 0x56, 0x34, 0x48, 0x69, 0x45, 0x7a, 0x70, 0x37, 0x70, 0x78, + 0x69, 0x44, 0x6d, 0x48, 0x68, 0x57, 0x76, 0x70, 0x34, 0x36, 0x37, 0x32, + 0x42, 0x62, 0x36, 0x69, 0x42, 0x47, 0x2b, 0x62, 0x73, 0x6a, 0x43, 0x55, + 0x4f, 0x45, 0x6b, 0x2f, 0x6e, 0x39, 0x6f, 0x39, 0x4b, 0x68, 0x5a, 0x7a, + 0x49, 0x42, 0x6c, 0x75, 0x52, 0x68, 0x74, 0x78, 0x43, 0x6d, 0x77, 0x35, + 0x0a, 0x6e, 0x77, 0x34, 0x44, 0x6f, 0x37, 0x7a, 0x30, 0x30, 0x50, 0x54, + 0x76, 0x4e, 0x38, 0x31, 0x32, 0x36, 0x30, 0x75, 0x50, 0x57, 0x53, 0x63, + 0x30, 0x34, 0x49, 0x72, 0x79, 0x74, 0x76, 0x5a, 0x55, 0x69, 0x41, 0x49, + 0x78, 0x2f, 0x35, 0x71, 0x78, 0x44, 0x37, 0x32, 0x62, 0x69, 0x6a, 0x32, + 0x78, 0x4a, 0x38, 0x74, 0x2f, 0x49, 0x39, 0x47, 0x49, 0x38, 0x67, 0x34, + 0x46, 0x74, 0x6f, 0x56, 0x42, 0x0a, 0x38, 0x70, 0x42, 0x36, 0x53, 0x2f, + 0x68, 0x4a, 0x58, 0x31, 0x50, 0x5a, 0x68, 0x68, 0x39, 0x56, 0x6c, 0x55, + 0x36, 0x59, 0x6b, 0x2b, 0x54, 0x4f, 0x66, 0x4f, 0x56, 0x6e, 0x62, 0x65, + 0x62, 0x47, 0x34, 0x57, 0x35, 0x31, 0x33, 0x38, 0x4c, 0x6b, 0x42, 0x38, + 0x33, 0x35, 0x65, 0x71, 0x6b, 0x33, 0x5a, 0x7a, 0x30, 0x71, 0x73, 0x62, + 0x63, 0x32, 0x65, 0x75, 0x6f, 0x69, 0x38, 0x48, 0x78, 0x69, 0x0a, 0x79, + 0x31, 0x56, 0x47, 0x77, 0x51, 0x45, 0x6d, 0x4d, 0x51, 0x36, 0x33, 0x6a, + 0x58, 0x7a, 0x34, 0x63, 0x36, 0x67, 0x2b, 0x58, 0x35, 0x35, 0x69, 0x66, + 0x76, 0x55, 0x4b, 0x39, 0x4a, 0x70, 0x6e, 0x35, 0x45, 0x38, 0x70, 0x71, + 0x2b, 0x70, 0x4d, 0x64, 0x37, 0x45, 0x43, 0x67, 0x59, 0x45, 0x41, 0x39, + 0x33, 0x6c, 0x59, 0x71, 0x2b, 0x43, 0x72, 0x35, 0x34, 0x4b, 0x34, 0x65, + 0x79, 0x35, 0x74, 0x0a, 0x73, 0x57, 0x4d, 0x61, 0x2b, 0x79, 0x65, 0x35, + 0x52, 0x71, 0x78, 0x6a, 0x7a, 0x67, 0x58, 0x6a, 0x32, 0x4b, 0x71, 0x72, + 0x35, 0x35, 0x6a, 0x62, 0x35, 0x34, 0x56, 0x57, 0x47, 0x37, 0x77, 0x70, + 0x32, 0x69, 0x47, 0x62, 0x67, 0x38, 0x46, 0x4d, 0x6c, 0x6b, 0x51, 0x77, + 0x7a, 0x54, 0x4a, 0x77, 0x65, 0x62, 0x7a, 0x44, 0x79, 0x43, 0x53, 0x61, + 0x74, 0x67, 0x75, 0x45, 0x5a, 0x4c, 0x75, 0x42, 0x0a, 0x67, 0x52, 0x47, + 0x72, 0x6f, 0x52, 0x6e, 0x73, 0x55, 0x4f, 0x79, 0x39, 0x76, 0x42, 0x76, + 0x68, 0x4b, 0x50, 0x4f, 0x63, 0x68, 0x39, 0x62, 0x66, 0x4b, 0x49, 0x6c, + 0x36, 0x71, 0x4f, 0x67, 0x7a, 0x4d, 0x4a, 0x42, 0x32, 0x36, 0x37, 0x66, + 0x42, 0x56, 0x57, 0x78, 0x35, 0x79, 0x62, 0x6e, 0x52, 0x62, 0x57, 0x4e, + 0x2f, 0x49, 0x37, 0x52, 0x76, 0x4d, 0x51, 0x66, 0x33, 0x6b, 0x2b, 0x39, + 0x79, 0x0a, 0x62, 0x69, 0x43, 0x49, 0x56, 0x6e, 0x78, 0x44, 0x4c, 0x45, + 0x45, 0x59, 0x79, 0x78, 0x37, 0x7a, 0x38, 0x35, 0x2f, 0x35, 0x71, 0x78, + 0x73, 0x58, 0x67, 0x2f, 0x4d, 0x43, 0x67, 0x59, 0x45, 0x41, 0x37, 0x77, + 0x6d, 0x57, 0x4b, 0x74, 0x43, 0x54, 0x6e, 0x30, 0x33, 0x32, 0x48, 0x79, + 0x39, 0x50, 0x38, 0x4f, 0x4c, 0x34, 0x39, 0x54, 0x30, 0x58, 0x36, 0x5a, + 0x38, 0x46, 0x6c, 0x6b, 0x44, 0x43, 0x0a, 0x52, 0x6b, 0x34, 0x32, 0x79, + 0x67, 0x72, 0x63, 0x2f, 0x4d, 0x55, 0x62, 0x75, 0x67, 0x71, 0x39, 0x52, + 0x47, 0x55, 0x78, 0x63, 0x43, 0x78, 0x6f, 0x49, 0x6d, 0x4f, 0x47, 0x39, + 0x4a, 0x58, 0x55, 0x70, 0x45, 0x74, 0x55, 0x65, 0x33, 0x31, 0x59, 0x44, + 0x6d, 0x32, 0x6a, 0x2b, 0x2f, 0x6e, 0x62, 0x76, 0x72, 0x6a, 0x6c, 0x36, + 0x2f, 0x62, 0x50, 0x32, 0x71, 0x57, 0x73, 0x30, 0x56, 0x37, 0x6c, 0x0a, + 0x64, 0x54, 0x4a, 0x6c, 0x36, 0x64, 0x41, 0x42, 0x50, 0x35, 0x31, 0x70, + 0x43, 0x77, 0x38, 0x2b, 0x6c, 0x34, 0x63, 0x57, 0x67, 0x42, 0x42, 0x58, + 0x30, 0x38, 0x4c, 0x6b, 0x65, 0x65, 0x6e, 0x38, 0x31, 0x32, 0x41, 0x41, + 0x46, 0x4e, 0x72, 0x6a, 0x6d, 0x44, 0x43, 0x6a, 0x58, 0x36, 0x72, 0x48, + 0x6a, 0x57, 0x48, 0x4c, 0x4a, 0x63, 0x70, 0x53, 0x31, 0x38, 0x66, 0x6e, + 0x52, 0x52, 0x6b, 0x50, 0x0a, 0x56, 0x31, 0x64, 0x2f, 0x41, 0x48, 0x57, + 0x58, 0x37, 0x4d, 0x4d, 0x43, 0x67, 0x59, 0x45, 0x41, 0x36, 0x47, 0x73, + 0x77, 0x32, 0x67, 0x75, 0x68, 0x70, 0x30, 0x5a, 0x66, 0x32, 0x47, 0x43, + 0x63, 0x61, 0x4e, 0x4b, 0x35, 0x44, 0x6c, 0x51, 0x61, 0x62, 0x38, 0x4f, + 0x4c, 0x34, 0x48, 0x77, 0x72, 0x70, 0x74, 0x74, 0x7a, 0x6f, 0x34, 0x6b, + 0x75, 0x54, 0x6c, 0x77, 0x74, 0x71, 0x4e, 0x4b, 0x70, 0x0a, 0x51, 0x39, + 0x48, 0x34, 0x61, 0x6c, 0x39, 0x71, 0x66, 0x46, 0x34, 0x43, 0x72, 0x31, + 0x54, 0x46, 0x79, 0x61, 0x39, 0x38, 0x2b, 0x45, 0x56, 0x59, 0x66, 0x38, + 0x79, 0x46, 0x52, 0x4d, 0x33, 0x4e, 0x4c, 0x4e, 0x6a, 0x5a, 0x70, 0x65, + 0x33, 0x67, 0x77, 0x59, 0x66, 0x32, 0x45, 0x65, 0x72, 0x6c, 0x4a, 0x6a, + 0x37, 0x56, 0x4c, 0x63, 0x61, 0x68, 0x77, 0x30, 0x4b, 0x4b, 0x7a, 0x6f, + 0x4e, 0x31, 0x0a, 0x51, 0x42, 0x45, 0x4e, 0x66, 0x77, 0x67, 0x50, 0x4c, + 0x52, 0x6b, 0x35, 0x73, 0x44, 0x6b, 0x78, 0x39, 0x56, 0x68, 0x53, 0x6d, + 0x63, 0x66, 0x6c, 0x2f, 0x64, 0x69, 0x4c, 0x72, 0x6f, 0x5a, 0x64, 0x70, + 0x41, 0x77, 0x74, 0x76, 0x33, 0x76, 0x6f, 0x34, 0x6e, 0x45, 0x6f, 0x78, + 0x65, 0x75, 0x47, 0x46, 0x62, 0x4b, 0x54, 0x47, 0x78, 0x33, 0x51, 0x6b, + 0x66, 0x30, 0x43, 0x67, 0x59, 0x45, 0x41, 0x0a, 0x78, 0x79, 0x52, 0x2b, + 0x64, 0x63, 0x62, 0x30, 0x35, 0x59, 0x67, 0x6d, 0x33, 0x77, 0x34, 0x6b, + 0x6c, 0x48, 0x51, 0x54, 0x6f, 0x77, 0x51, 0x31, 0x30, 0x73, 0x31, 0x48, + 0x38, 0x30, 0x69, 0x61, 0x55, 0x63, 0x5a, 0x42, 0x67, 0x51, 0x75, 0x52, + 0x31, 0x67, 0x68, 0x45, 0x74, 0x44, 0x62, 0x55, 0x50, 0x5a, 0x48, 0x73, + 0x6f, 0x52, 0x35, 0x74, 0x31, 0x78, 0x43, 0x42, 0x30, 0x32, 0x79, 0x73, + 0x0a, 0x44, 0x67, 0x41, 0x77, 0x4c, 0x76, 0x31, 0x62, 0x43, 0x68, 0x49, + 0x76, 0x78, 0x76, 0x48, 0x2f, 0x4c, 0x36, 0x4b, 0x4d, 0x38, 0x6f, 0x76, + 0x5a, 0x32, 0x4c, 0x65, 0x6b, 0x42, 0x58, 0x34, 0x41, 0x76, 0x69, 0x57, + 0x78, 0x6f, 0x42, 0x78, 0x4a, 0x6e, 0x66, 0x7a, 0x2f, 0x45, 0x56, 0x61, + 0x75, 0x39, 0x38, 0x42, 0x30, 0x62, 0x31, 0x61, 0x75, 0x52, 0x4e, 0x36, + 0x65, 0x53, 0x43, 0x38, 0x33, 0x0a, 0x46, 0x52, 0x75, 0x47, 0x6c, 0x64, + 0x6c, 0x53, 0x4f, 0x57, 0x31, 0x7a, 0x2f, 0x6e, 0x53, 0x68, 0x38, 0x56, + 0x69, 0x69, 0x7a, 0x53, 0x59, 0x45, 0x35, 0x48, 0x35, 0x48, 0x58, 0x31, + 0x71, 0x6b, 0x58, 0x45, 0x69, 0x70, 0x70, 0x76, 0x46, 0x52, 0x45, 0x38, + 0x38, 0x43, 0x67, 0x59, 0x42, 0x33, 0x42, 0x66, 0x75, 0x33, 0x59, 0x51, + 0x59, 0x36, 0x30, 0x49, 0x54, 0x57, 0x49, 0x53, 0x68, 0x76, 0x0a, 0x6e, + 0x4e, 0x6b, 0x64, 0x63, 0x62, 0x54, 0x54, 0x39, 0x65, 0x6f, 0x50, 0x39, + 0x73, 0x75, 0x61, 0x52, 0x4a, 0x6a, 0x77, 0x39, 0x32, 0x4c, 0x6e, 0x2b, + 0x37, 0x5a, 0x70, 0x41, 0x4c, 0x59, 0x6c, 0x51, 0x4d, 0x4b, 0x55, 0x5a, + 0x6d, 0x4a, 0x2f, 0x35, 0x75, 0x42, 0x6d, 0x4c, 0x73, 0x34, 0x52, 0x46, + 0x77, 0x55, 0x54, 0x51, 0x72, 0x75, 0x4c, 0x4f, 0x50, 0x4c, 0x34, 0x79, + 0x4c, 0x54, 0x48, 0x0a, 0x61, 0x77, 0x41, 0x44, 0x57, 0x55, 0x7a, 0x73, + 0x33, 0x49, 0x52, 0x72, 0x31, 0x66, 0x77, 0x6e, 0x39, 0x45, 0x2b, 0x7a, + 0x4d, 0x38, 0x4a, 0x56, 0x79, 0x4b, 0x43, 0x6e, 0x55, 0x45, 0x4d, 0x33, + 0x77, 0x34, 0x4e, 0x35, 0x55, 0x5a, 0x73, 0x6b, 0x47, 0x4f, 0x32, 0x6b, + 0x6c, 0x61, 0x73, 0x68, 0x41, 0x64, 0x33, 0x30, 0x68, 0x57, 0x4f, 0x2b, + 0x6b, 0x6e, 0x52, 0x76, 0x2f, 0x79, 0x30, 0x72, 0x0a, 0x75, 0x47, 0x49, + 0x59, 0x73, 0x39, 0x45, 0x6b, 0x37, 0x59, 0x58, 0x6c, 0x58, 0x49, 0x52, + 0x56, 0x72, 0x7a, 0x4d, 0x77, 0x63, 0x73, 0x72, 0x74, 0x31, 0x77, 0x3d, + 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x50, + 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x20, 0x4b, 0x45, 0x59, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; diff --git a/test/core/end2end/data/test_root_cert.cc b/test/core/end2end/data/test_root_cert.cc index b4771b2cb8d..941ebc82dc8 100644 --- a/test/core/end2end/data/test_root_cert.cc +++ b/test/core/end2end/data/test_root_cert.cc @@ -19,68 +19,104 @@ extern const char test_root_cert[] = { 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x49, 0x7a, 0x43, 0x43, - 0x41, 0x59, 0x77, 0x43, 0x43, 0x51, 0x43, 0x46, 0x54, 0x62, 0x46, 0x37, - 0x58, 0x4e, 0x53, 0x76, 0x76, 0x6a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, - 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, - 0x41, 0x44, 0x42, 0x57, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, - 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x42, 0x0a, 0x56, 0x54, 0x45, - 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, - 0x4b, 0x55, 0x32, 0x39, 0x74, 0x5a, 0x53, 0x31, 0x54, 0x64, 0x47, 0x46, - 0x30, 0x5a, 0x54, 0x45, 0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, - 0x45, 0x43, 0x67, 0x77, 0x59, 0x53, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, - 0x75, 0x5a, 0x58, 0x51, 0x67, 0x56, 0x32, 0x6c, 0x6b, 0x5a, 0x32, 0x6c, - 0x30, 0x0a, 0x63, 0x79, 0x42, 0x51, 0x64, 0x48, 0x6b, 0x67, 0x54, 0x48, - 0x52, 0x6b, 0x4d, 0x51, 0x38, 0x77, 0x44, 0x51, 0x59, 0x44, 0x56, 0x51, - 0x51, 0x44, 0x44, 0x41, 0x5a, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x59, 0x32, - 0x45, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x51, 0x77, 0x4e, 0x7a, - 0x45, 0x33, 0x4d, 0x6a, 0x4d, 0x78, 0x4e, 0x7a, 0x55, 0x78, 0x57, 0x68, - 0x63, 0x4e, 0x4d, 0x6a, 0x51, 0x77, 0x0a, 0x4e, 0x7a, 0x45, 0x30, 0x4d, - 0x6a, 0x4d, 0x78, 0x4e, 0x7a, 0x55, 0x78, 0x57, 0x6a, 0x42, 0x57, 0x4d, - 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, - 0x77, 0x4a, 0x42, 0x56, 0x54, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, - 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x4b, 0x55, 0x32, 0x39, 0x74, 0x5a, - 0x53, 0x31, 0x54, 0x64, 0x47, 0x46, 0x30, 0x5a, 0x54, 0x45, 0x68, 0x0a, - 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x59, - 0x53, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x5a, 0x58, 0x51, 0x67, - 0x56, 0x32, 0x6c, 0x6b, 0x5a, 0x32, 0x6c, 0x30, 0x63, 0x79, 0x42, 0x51, - 0x64, 0x48, 0x6b, 0x67, 0x54, 0x48, 0x52, 0x6b, 0x4d, 0x51, 0x38, 0x77, - 0x44, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x41, 0x5a, 0x30, - 0x5a, 0x58, 0x4e, 0x30, 0x0a, 0x59, 0x32, 0x45, 0x77, 0x67, 0x5a, 0x38, - 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, - 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44, 0x67, 0x59, 0x30, - 0x41, 0x4d, 0x49, 0x47, 0x4a, 0x41, 0x6f, 0x47, 0x42, 0x41, 0x4d, 0x42, - 0x41, 0x33, 0x77, 0x56, 0x65, 0x54, 0x47, 0x48, 0x5a, 0x52, 0x31, 0x52, - 0x79, 0x65, 0x2f, 0x69, 0x2b, 0x4a, 0x38, 0x61, 0x32, 0x0a, 0x63, 0x75, - 0x35, 0x67, 0x58, 0x77, 0x46, 0x56, 0x36, 0x54, 0x6e, 0x4f, 0x62, 0x7a, - 0x47, 0x4d, 0x37, 0x62, 0x4c, 0x46, 0x43, 0x4f, 0x35, 0x69, 0x39, 0x76, - 0x34, 0x6d, 0x4c, 0x6f, 0x34, 0x69, 0x46, 0x7a, 0x50, 0x73, 0x48, 0x6d, - 0x57, 0x44, 0x55, 0x78, 0x4b, 0x53, 0x33, 0x59, 0x38, 0x69, 0x58, 0x62, - 0x75, 0x30, 0x65, 0x59, 0x42, 0x6c, 0x4c, 0x6f, 0x4e, 0x59, 0x30, 0x6c, - 0x53, 0x76, 0x0a, 0x78, 0x44, 0x78, 0x33, 0x33, 0x4f, 0x2b, 0x44, 0x75, - 0x77, 0x4d, 0x6d, 0x56, 0x4e, 0x2b, 0x44, 0x7a, 0x53, 0x44, 0x2b, 0x45, - 0x6f, 0x64, 0x39, 0x7a, 0x66, 0x76, 0x77, 0x4f, 0x57, 0x48, 0x73, 0x61, - 0x7a, 0x59, 0x43, 0x5a, 0x54, 0x32, 0x50, 0x68, 0x4e, 0x78, 0x6e, 0x56, - 0x57, 0x49, 0x75, 0x4a, 0x58, 0x56, 0x69, 0x59, 0x34, 0x4a, 0x41, 0x48, - 0x55, 0x47, 0x6f, 0x64, 0x6a, 0x78, 0x2b, 0x0a, 0x51, 0x41, 0x69, 0x36, - 0x79, 0x43, 0x41, 0x75, 0x72, 0x55, 0x5a, 0x47, 0x76, 0x59, 0x58, 0x47, - 0x67, 0x5a, 0x53, 0x42, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x45, 0x77, - 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, - 0x41, 0x51, 0x45, 0x46, 0x42, 0x51, 0x41, 0x44, 0x67, 0x59, 0x45, 0x41, - 0x51, 0x6f, 0x51, 0x56, 0x44, 0x38, 0x62, 0x77, 0x64, 0x74, 0x57, 0x4a, - 0x0a, 0x41, 0x6e, 0x69, 0x47, 0x42, 0x77, 0x63, 0x43, 0x66, 0x71, 0x59, - 0x79, 0x48, 0x2b, 0x2f, 0x4b, 0x70, 0x41, 0x31, 0x30, 0x41, 0x63, 0x65, - 0x62, 0x4a, 0x56, 0x56, 0x54, 0x79, 0x59, 0x62, 0x59, 0x76, 0x49, 0x39, - 0x51, 0x38, 0x64, 0x36, 0x52, 0x53, 0x56, 0x75, 0x34, 0x50, 0x5a, 0x79, - 0x39, 0x4f, 0x41, 0x4c, 0x48, 0x52, 0x2f, 0x51, 0x72, 0x57, 0x42, 0x64, - 0x59, 0x54, 0x41, 0x79, 0x7a, 0x0a, 0x66, 0x4e, 0x41, 0x6d, 0x63, 0x32, - 0x63, 0x6d, 0x64, 0x6b, 0x53, 0x52, 0x4a, 0x7a, 0x6a, 0x68, 0x49, 0x61, - 0x4f, 0x73, 0x74, 0x6e, 0x51, 0x79, 0x31, 0x4a, 0x2b, 0x46, 0x6b, 0x30, - 0x54, 0x39, 0x58, 0x79, 0x76, 0x51, 0x74, 0x71, 0x34, 0x39, 0x39, 0x79, - 0x46, 0x62, 0x71, 0x39, 0x78, 0x6f, 0x67, 0x55, 0x56, 0x6c, 0x45, 0x47, - 0x48, 0x36, 0x32, 0x78, 0x50, 0x36, 0x76, 0x48, 0x30, 0x59, 0x0a, 0x35, - 0x75, 0x6b, 0x4b, 0x2f, 0x2f, 0x64, 0x43, 0x50, 0x41, 0x7a, 0x41, 0x31, - 0x31, 0x59, 0x75, 0x58, 0x32, 0x72, 0x6e, 0x65, 0x78, 0x30, 0x4a, 0x68, - 0x75, 0x54, 0x51, 0x66, 0x63, 0x49, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, - 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x00}; + 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44, 0x57, 0x6a, 0x43, 0x43, + 0x41, 0x6b, 0x4b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55, + 0x57, 0x72, 0x50, 0x30, 0x56, 0x76, 0x48, 0x63, 0x79, 0x2b, 0x4c, 0x50, + 0x36, 0x55, 0x75, 0x59, 0x4e, 0x74, 0x69, 0x4c, 0x39, 0x67, 0x42, 0x68, + 0x44, 0x35, 0x6f, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a, 0x49, + 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x0a, 0x42, 0x51, 0x41, + 0x77, 0x56, 0x6a, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, + 0x45, 0x42, 0x68, 0x4d, 0x43, 0x51, 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, + 0x52, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, + 0x76, 0x62, 0x57, 0x55, 0x74, 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, + 0x78, 0x49, 0x54, 0x41, 0x66, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, + 0x4d, 0x0a, 0x47, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, + 0x56, 0x30, 0x49, 0x46, 0x64, 0x70, 0x5a, 0x47, 0x64, 0x70, 0x64, 0x48, + 0x4d, 0x67, 0x55, 0x48, 0x52, 0x35, 0x49, 0x45, 0x78, 0x30, 0x5a, 0x44, + 0x45, 0x50, 0x4d, 0x41, 0x30, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, + 0x77, 0x47, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x47, 0x4e, 0x68, 0x4d, 0x42, + 0x34, 0x58, 0x44, 0x54, 0x49, 0x77, 0x0a, 0x4d, 0x44, 0x4d, 0x78, 0x4e, + 0x7a, 0x45, 0x34, 0x4e, 0x54, 0x6b, 0x31, 0x4d, 0x56, 0x6f, 0x58, 0x44, + 0x54, 0x4d, 0x77, 0x4d, 0x44, 0x4d, 0x78, 0x4e, 0x54, 0x45, 0x34, 0x4e, + 0x54, 0x6b, 0x31, 0x4d, 0x56, 0x6f, 0x77, 0x56, 0x6a, 0x45, 0x4c, 0x4d, + 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x51, + 0x56, 0x55, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56, 0x0a, + 0x42, 0x41, 0x67, 0x4d, 0x43, 0x6c, 0x4e, 0x76, 0x62, 0x57, 0x55, 0x74, + 0x55, 0x33, 0x52, 0x68, 0x64, 0x47, 0x55, 0x78, 0x49, 0x54, 0x41, 0x66, + 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x4d, 0x47, 0x45, 0x6c, 0x75, + 0x64, 0x47, 0x56, 0x79, 0x62, 0x6d, 0x56, 0x30, 0x49, 0x46, 0x64, 0x70, + 0x5a, 0x47, 0x64, 0x70, 0x64, 0x48, 0x4d, 0x67, 0x55, 0x48, 0x52, 0x35, + 0x49, 0x45, 0x78, 0x30, 0x0a, 0x5a, 0x44, 0x45, 0x50, 0x4d, 0x41, 0x30, + 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77, 0x47, 0x64, 0x47, 0x56, + 0x7a, 0x64, 0x47, 0x4e, 0x68, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, + 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, + 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, + 0x41, 0x4d, 0x49, 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x0a, 0x41, 0x51, + 0x45, 0x41, 0x73, 0x47, 0x4c, 0x30, 0x6f, 0x58, 0x66, 0x6c, 0x46, 0x30, + 0x4c, 0x7a, 0x6f, 0x4d, 0x2b, 0x42, 0x68, 0x2b, 0x71, 0x55, 0x55, 0x39, + 0x79, 0x68, 0x71, 0x7a, 0x77, 0x32, 0x77, 0x38, 0x4f, 0x4f, 0x58, 0x35, + 0x6d, 0x75, 0x2f, 0x69, 0x4e, 0x43, 0x79, 0x55, 0x4f, 0x42, 0x72, 0x71, + 0x61, 0x48, 0x69, 0x37, 0x6d, 0x47, 0x48, 0x78, 0x37, 0x33, 0x47, 0x44, + 0x30, 0x31, 0x0a, 0x64, 0x69, 0x4e, 0x7a, 0x43, 0x7a, 0x76, 0x6c, 0x63, + 0x51, 0x71, 0x64, 0x4e, 0x49, 0x48, 0x36, 0x4e, 0x51, 0x53, 0x4c, 0x37, + 0x44, 0x54, 0x70, 0x42, 0x6a, 0x63, 0x61, 0x36, 0x36, 0x6a, 0x59, 0x54, + 0x39, 0x75, 0x37, 0x33, 0x76, 0x5a, 0x65, 0x32, 0x4d, 0x44, 0x72, 0x72, + 0x31, 0x6e, 0x56, 0x62, 0x75, 0x4c, 0x76, 0x66, 0x75, 0x39, 0x38, 0x35, + 0x30, 0x63, 0x64, 0x78, 0x69, 0x55, 0x4f, 0x0a, 0x49, 0x6e, 0x76, 0x35, + 0x78, 0x66, 0x38, 0x2b, 0x73, 0x54, 0x48, 0x47, 0x30, 0x43, 0x2b, 0x61, + 0x2b, 0x56, 0x41, 0x76, 0x4d, 0x68, 0x73, 0x4c, 0x69, 0x52, 0x6a, 0x73, + 0x71, 0x2b, 0x6c, 0x58, 0x4b, 0x52, 0x4a, 0x79, 0x6b, 0x35, 0x7a, 0x6b, + 0x62, 0x62, 0x73, 0x45, 0x54, 0x79, 0x62, 0x71, 0x70, 0x78, 0x6f, 0x4a, + 0x2b, 0x4b, 0x37, 0x43, 0x6f, 0x53, 0x79, 0x33, 0x79, 0x63, 0x2f, 0x6b, + 0x0a, 0x51, 0x49, 0x59, 0x33, 0x54, 0x69, 0x70, 0x77, 0x45, 0x74, 0x77, + 0x6b, 0x4b, 0x50, 0x34, 0x68, 0x7a, 0x79, 0x6f, 0x36, 0x4b, 0x69, 0x47, + 0x64, 0x2f, 0x44, 0x50, 0x65, 0x78, 0x69, 0x65, 0x34, 0x6e, 0x42, 0x55, + 0x49, 0x6e, 0x4e, 0x33, 0x62, 0x53, 0x31, 0x42, 0x55, 0x65, 0x4e, 0x5a, + 0x35, 0x7a, 0x65, 0x61, 0x49, 0x43, 0x32, 0x65, 0x67, 0x33, 0x62, 0x6b, + 0x65, 0x65, 0x57, 0x37, 0x63, 0x0a, 0x71, 0x54, 0x35, 0x35, 0x62, 0x2b, + 0x59, 0x65, 0x6e, 0x36, 0x43, 0x78, 0x59, 0x30, 0x54, 0x45, 0x6b, 0x7a, + 0x42, 0x4b, 0x36, 0x41, 0x4b, 0x74, 0x2f, 0x57, 0x55, 0x69, 0x61, 0x6c, + 0x4b, 0x4d, 0x67, 0x54, 0x30, 0x77, 0x62, 0x54, 0x78, 0x52, 0x5a, 0x4f, + 0x37, 0x6b, 0x55, 0x43, 0x48, 0x33, 0x53, 0x71, 0x36, 0x65, 0x2f, 0x77, + 0x58, 0x65, 0x46, 0x64, 0x4a, 0x2b, 0x48, 0x76, 0x64, 0x56, 0x0a, 0x4c, + 0x50, 0x6c, 0x41, 0x67, 0x35, 0x54, 0x6e, 0x4d, 0x61, 0x4e, 0x70, 0x52, + 0x64, 0x51, 0x69, 0x68, 0x2f, 0x38, 0x6e, 0x52, 0x46, 0x70, 0x73, 0x64, + 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x79, 0x41, 0x77, 0x48, + 0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x45, 0x42, + 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, 0x41, 0x34, 0x47, 0x41, + 0x31, 0x55, 0x64, 0x0a, 0x44, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x45, + 0x41, 0x77, 0x49, 0x43, 0x42, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, + 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, + 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x6b, 0x54, 0x72, 0x4b, + 0x5a, 0x6a, 0x42, 0x72, 0x4a, 0x58, 0x48, 0x70, 0x73, 0x2f, 0x48, 0x72, + 0x6a, 0x4e, 0x43, 0x46, 0x50, 0x62, 0x35, 0x61, 0x0a, 0x54, 0x48, 0x75, + 0x47, 0x50, 0x43, 0x53, 0x73, 0x65, 0x70, 0x65, 0x31, 0x77, 0x6b, 0x4b, + 0x64, 0x53, 0x70, 0x31, 0x68, 0x34, 0x48, 0x47, 0x52, 0x70, 0x4c, 0x6f, + 0x43, 0x67, 0x63, 0x4c, 0x79, 0x73, 0x43, 0x4a, 0x35, 0x68, 0x5a, 0x68, + 0x52, 0x70, 0x48, 0x6b, 0x52, 0x69, 0x68, 0x68, 0x65, 0x66, 0x2b, 0x72, + 0x46, 0x48, 0x45, 0x65, 0x36, 0x30, 0x55, 0x65, 0x50, 0x51, 0x4f, 0x33, + 0x53, 0x0a, 0x43, 0x56, 0x54, 0x74, 0x64, 0x4a, 0x42, 0x34, 0x43, 0x59, + 0x57, 0x70, 0x63, 0x4e, 0x79, 0x58, 0x4f, 0x64, 0x71, 0x65, 0x66, 0x72, + 0x62, 0x4a, 0x57, 0x35, 0x51, 0x4e, 0x6c, 0x6a, 0x78, 0x67, 0x69, 0x36, + 0x46, 0x68, 0x76, 0x73, 0x37, 0x4a, 0x4a, 0x6b, 0x42, 0x71, 0x64, 0x58, + 0x49, 0x6b, 0x57, 0x58, 0x74, 0x46, 0x6b, 0x32, 0x65, 0x52, 0x67, 0x4f, + 0x49, 0x50, 0x32, 0x45, 0x6f, 0x39, 0x0a, 0x2f, 0x4f, 0x48, 0x51, 0x48, + 0x6c, 0x59, 0x6e, 0x77, 0x5a, 0x46, 0x72, 0x6b, 0x36, 0x73, 0x70, 0x34, + 0x77, 0x50, 0x79, 0x52, 0x2b, 0x41, 0x39, 0x35, 0x53, 0x30, 0x74, 0x6f, + 0x5a, 0x42, 0x63, 0x79, 0x44, 0x56, 0x7a, 0x37, 0x75, 0x2b, 0x68, 0x4f, + 0x57, 0x30, 0x70, 0x47, 0x4b, 0x33, 0x77, 0x76, 0x69, 0x4f, 0x65, 0x39, + 0x6c, 0x76, 0x52, 0x67, 0x6a, 0x2f, 0x48, 0x33, 0x50, 0x77, 0x74, 0x0a, + 0x62, 0x65, 0x77, 0x62, 0x30, 0x6c, 0x2b, 0x4d, 0x68, 0x52, 0x69, 0x67, + 0x30, 0x2f, 0x44, 0x56, 0x48, 0x61, 0x6d, 0x79, 0x56, 0x78, 0x72, 0x44, + 0x52, 0x62, 0x71, 0x49, 0x6e, 0x55, 0x31, 0x2f, 0x47, 0x54, 0x4e, 0x43, + 0x77, 0x63, 0x5a, 0x6b, 0x58, 0x4b, 0x59, 0x46, 0x57, 0x53, 0x66, 0x39, + 0x32, 0x55, 0x2b, 0x6b, 0x49, 0x63, 0x54, 0x74, 0x68, 0x32, 0x34, 0x51, + 0x31, 0x67, 0x63, 0x77, 0x0a, 0x65, 0x5a, 0x69, 0x4c, 0x6c, 0x35, 0x46, + 0x66, 0x72, 0x57, 0x6f, 0x6b, 0x55, 0x4e, 0x79, 0x74, 0x46, 0x45, 0x6c, + 0x58, 0x6f, 0x62, 0x30, 0x56, 0x30, 0x61, 0x35, 0x2f, 0x6b, 0x62, 0x68, + 0x69, 0x4c, 0x63, 0x33, 0x79, 0x57, 0x6d, 0x76, 0x57, 0x71, 0x48, 0x54, + 0x70, 0x71, 0x43, 0x41, 0x4c, 0x62, 0x56, 0x79, 0x46, 0x2b, 0x72, 0x4b, + 0x4a, 0x6f, 0x32, 0x66, 0x35, 0x4b, 0x77, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, + 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, + 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, + 0x00}; diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 38efc2f1cae..2b73af6f715 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -32,7 +32,8 @@ def _fixture_options( supports_proxy_auth = False, supports_write_buffering = True, client_channel = True, - supports_msvc = True): + supports_msvc = True, + flaky_tests = []): return struct( fullstack = fullstack, includes_proxy = includes_proxy, @@ -47,6 +48,7 @@ def _fixture_options( client_channel = client_channel, supports_msvc = supports_msvc, _platforms = _platforms, + flaky_tests = flaky_tests, ) # maps fixture name to whether it requires the security library @@ -62,6 +64,7 @@ END2END_FIXTURES = { fullstack = False, client_channel = False, _platforms = ["linux", "mac", "posix"], + flaky_tests = ["resource_quota_server"], # TODO(b/151212019) ), "h2_full": _fixture_options(), "h2_full+pipe": _fixture_options(_platforms = ["linux"]), @@ -89,13 +92,19 @@ END2END_FIXTURES = { "h2_ssl": _fixture_options(secure = True), "h2_ssl_cred_reload": _fixture_options(secure = True), "h2_tls": _fixture_options(secure = True), - "h2_local_uds": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), + "h2_local_uds": _fixture_options( + secure = True, + dns_resolver = False, + _platforms = ["linux", "mac", "posix"], + flaky_tests = ["resource_quota_server"], # TODO(b/151212019) + ), "h2_local_ipv4": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), "h2_local_ipv6": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]), "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = True), "h2_uds": _fixture_options( dns_resolver = False, _platforms = ["linux", "mac", "posix"], + flaky_tests = ["resource_quota_server"], # TODO(b/151212019) ), "inproc": _fixture_options( secure = True, @@ -124,6 +133,7 @@ END2END_NOSEC_FIXTURES = { secure = False, _platforms = ["linux", "mac", "posix"], supports_msvc = False, + flaky_tests = ["resource_quota_server"], # TODO(b/151212019) ), "h2_full": _fixture_options(secure = False), "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"], supports_msvc = False), @@ -158,6 +168,7 @@ END2END_NOSEC_FIXTURES = { _platforms = ["linux", "mac", "posix"], secure = False, supports_msvc = False, + flaky_tests = ["resource_quota_server"], # TODO(b/151212019) ), } @@ -172,7 +183,8 @@ def _test_options( needs_http2 = False, needs_proxy_auth = False, needs_write_buffering = False, - needs_client_channel = False): + needs_client_channel = False, + short_name = None): return struct( needs_fullstack = needs_fullstack, needs_dns = needs_dns, @@ -185,6 +197,7 @@ def _test_options( needs_proxy_auth = needs_proxy_auth, needs_write_buffering = needs_write_buffering, needs_client_channel = needs_client_channel, + short_name = short_name, ) # maps test names to options @@ -273,12 +286,21 @@ END2END_TESTS = { "retry_exceeds_buffer_size_in_subsequent_batch": _test_options( needs_client_channel = True, proxyable = False, + # TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE + # See b/151617965 + short_name = "retry_exceeds_buffer_size_in_subseq", ), "retry_non_retriable_status": _test_options( needs_client_channel = True, proxyable = False, ), - "retry_non_retriable_status_before_recv_trailing_metadata_started": _test_options(needs_client_channel = True, proxyable = False), + "retry_non_retriable_status_before_recv_trailing_metadata_started": _test_options( + needs_client_channel = True, + proxyable = False, + # TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE + # See b/151617965 + short_name = "retry_non_retriable_status2", + ), "retry_recv_initial_metadata": _test_options( needs_client_channel = True, proxyable = False, @@ -303,6 +325,9 @@ END2END_TESTS = { "retry_streaming_succeeds_before_replay_finished": _test_options( needs_client_channel = True, proxyable = False, + # TODO(jtattermusch): too long bazel test name makes the test flaky on Windows RBE + # See b/151617965 + short_name = "retry_streaming2", ), "retry_throttled": _test_options( needs_client_channel = True, @@ -418,8 +443,9 @@ def grpc_end2end_tests(): if not _compatible(fopt, topt): continue + test_short_name = str(t) if not topt.short_name else topt.short_name native.sh_test( - name = "%s_test@%s" % (f, t), + name = "%s_test@%s" % (f, test_short_name), data = [":%s_test" % f], srcs = ["end2end_test.sh"], args = [ @@ -427,11 +453,12 @@ def grpc_end2end_tests(): t, ], tags = ["no_linux"] + _platform_support_tags(fopt), + flaky = t in fopt.flaky_tests, ) for poller in POLLERS: native.sh_test( - name = "%s_test@%s@poller=%s" % (f, t, poller), + name = "%s_test@%s@poller=%s" % (f, test_short_name, poller), data = [":%s_test" % f], srcs = ["end2end_test.sh"], args = [ @@ -440,6 +467,7 @@ def grpc_end2end_tests(): poller, ], tags = ["no_mac", "no_windows"], + flaky = t in fopt.flaky_tests, ) def grpc_end2end_nosec_tests(): @@ -486,8 +514,9 @@ def grpc_end2end_nosec_tests(): if topt.secure: continue + test_short_name = str(t) if not topt.short_name else topt.short_name native.sh_test( - name = "%s_nosec_test@%s" % (f, t), + name = "%s_nosec_test@%s" % (f, test_short_name), data = [":%s_nosec_test" % f], srcs = ["end2end_test.sh"], args = [ @@ -495,11 +524,12 @@ def grpc_end2end_nosec_tests(): t, ], tags = ["no_linux"] + _platform_support_tags(fopt), + flaky = t in fopt.flaky_tests, ) for poller in POLLERS: native.sh_test( - name = "%s_nosec_test@%s@poller=%s" % (f, t, poller), + name = "%s_nosec_test@%s@poller=%s" % (f, test_short_name, poller), data = [":%s_nosec_test" % f], srcs = ["end2end_test.sh"], args = [ @@ -508,4 +538,5 @@ def grpc_end2end_nosec_tests(): poller, ], tags = ["no_mac", "no_windows"], + flaky = t in fopt.flaky_tests, ) diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 64603cbc1fc..1ad61154158 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -47,7 +47,8 @@ static int g_resolve_port = -1; static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, bool check_grpclb, + std::unique_ptr* addresses, + std::unique_ptr* balancer_addresses, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner); @@ -104,13 +105,14 @@ static grpc_address_resolver_vtable test_resolver = { static grpc_ares_request* my_dns_lookup_ares_locked( const char* dns_server, const char* addr, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, - std::unique_ptr* addresses, bool check_grpclb, + std::unique_ptr* addresses, + std::unique_ptr* balancer_addresses, char** service_config_json, int query_timeout_ms, grpc_core::Combiner* combiner) { if (0 != strcmp(addr, "test")) { return iomgr_dns_lookup_ares_locked( dns_server, addr, default_port, interested_parties, on_done, addresses, - check_grpclb, service_config_json, query_timeout_ms, combiner); + balancer_addresses, service_config_json, query_timeout_ms, combiner); } grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/core/end2end/tests/disappearing_server.cc b/test/core/end2end/tests/disappearing_server.cc index 1380b5c362b..280ae7dd00a 100644 --- a/test/core/end2end/tests/disappearing_server.cc +++ b/test/core/end2end/tests/disappearing_server.cc @@ -210,7 +210,9 @@ static void disappearing_server_test(grpc_end2end_test_config config) { void disappearing_server(grpc_end2end_test_config config) { GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION); +#ifndef GPR_WINDOWS /* b/148110727 for more details */ disappearing_server_test(config); +#endif /* GPR_WINDOWS */ } void disappearing_server_pre_init(void) {} diff --git a/test/core/fling/BUILD b/test/core/fling/BUILD index d1871e99648..d037142b545 100644 --- a/test/core/fling/BUILD +++ b/test/core/fling/BUILD @@ -47,7 +47,7 @@ grpc_cc_binary( ) grpc_cc_test( - name = "fling", + name = "fling_test", srcs = ["fling_test.cc"], data = [ ":fling_client", @@ -63,7 +63,7 @@ grpc_cc_test( ) grpc_cc_test( - name = "fling_stream", + name = "fling_stream_test", srcs = ["fling_stream_test.cc"], data = [ ":fling_client", diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD index 77ffc066ad9..24dc1431396 100644 --- a/test/core/handshake/BUILD +++ b/test/core/handshake/BUILD @@ -19,7 +19,7 @@ grpc_package(name = "test/core/handshake") licenses(["notice"]) # Apache v2 grpc_cc_test( - name = "client_ssl", + name = "client_ssl_test", srcs = ["client_ssl.cc"], data = [ "//src/core/tsi/test_creds:ca.pem", @@ -48,7 +48,7 @@ grpc_cc_library( ) grpc_cc_test( - name = "server_ssl", + name = "server_ssl_test", srcs = ["server_ssl.cc"], data = [ "//src/core/tsi/test_creds:ca.pem", @@ -66,7 +66,7 @@ grpc_cc_test( ) grpc_cc_test( - name = "handshake_server_with_readahead_handshaker", + name = "handshake_server_with_readahead_handshaker_test", srcs = ["readahead_handshaker_server_ssl.cc"], data = [ "//src/core/tsi/test_creds:ca.pem", @@ -84,7 +84,7 @@ grpc_cc_test( ) grpc_cc_test( - name = "handshake_verify_peer_options", + name = "handshake_verify_peer_options_test", srcs = ["verify_peer_options.cc"], data = [ "//src/core/tsi/test_creds:ca.pem", diff --git a/test/core/security/grpc_tls_credentials_options_test.cc b/test/core/security/grpc_tls_credentials_options_test.cc index 95bb502e2cf..142aabf5858 100644 --- a/test/core/security/grpc_tls_credentials_options_test.cc +++ b/test/core/security/grpc_tls_credentials_options_test.cc @@ -50,6 +50,13 @@ TEST(GrpcTlsCredentialsOptionsTest, SetKeyMaterials) { delete config; } +TEST(GrpcTlsCredentialsOptionsTest, ErrorDetails) { + grpc_tls_error_details error_details; + EXPECT_STREQ(error_details.error_details().c_str(), ""); + error_details.set_error_details("test error details"); + EXPECT_STREQ(error_details.error_details().c_str(), "test error details"); +} + } // namespace testing int main(int argc, char** argv) { diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD index 3d2c51e887b..ad36d1c40a6 100644 --- a/test/core/surface/BUILD +++ b/test/core/surface/BUILD @@ -135,6 +135,7 @@ grpc_cc_test( grpc_cc_test( name = "sequential_connectivity_test", srcs = ["sequential_connectivity_test.cc"], + flaky = True, # TODO(b/151696318) language = "C++", deps = [ "//:gpr", diff --git a/test/core/transport/chttp2/settings_timeout_test.cc b/test/core/transport/chttp2/settings_timeout_test.cc index 5edf61c28bd..8680f208b57 100644 --- a/test/core/transport/chttp2/settings_timeout_test.cc +++ b/test/core/transport/chttp2/settings_timeout_test.cc @@ -196,7 +196,7 @@ class Client { GRPC_LOG_IF_ERROR( "grpc_pollset_work", grpc_pollset_work(pollset_, &worker, - grpc_core::ExecCtx::Get()->Now() + 1000)); + grpc_core::ExecCtx::Get()->Now() + 100)); // Flushes any work scheduled before or during polling. grpc_core::ExecCtx::Get()->Flush(); gpr_mu_unlock(mu_); diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 844a12c261e..70b8355bc79 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -16,23 +16,23 @@ * */ +#include "src/core/tsi/ssl_transport_security.h" + +#include +#include +#include +#include #include #include #include #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/security_connector/security_connector.h" -#include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" #include "test/core/tsi/transport_security_test_lib.h" #include "test/core/util/test_config.h" -#include -#include -#include -#include - extern "C" { #include #include @@ -45,6 +45,7 @@ extern "C" { #define SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM 2 #define SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM 1 #define SSL_TSI_TEST_CREDENTIALS_DIR "src/core/tsi/test_creds/" +#define SSL_TSI_TEST_WRONG_SNI "test.google.cn" // OpenSSL 1.1 uses AES256 for encryption session ticket by default so specify // different STEK size. @@ -235,6 +236,9 @@ void check_server0_peer(tsi_peer* peer) { nullptr); GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au") == 1); GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au") == 1); + GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "BAR.TEST.GOOGLE.COM.AU") == 1); + GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "Bar.Test.Google.Com.Au") == 1); + GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "bAr.TeST.gOOgle.cOm.AU") == 1); GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "bar.test.google.blah") == 0); GPR_ASSERT(tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au") == 0); @@ -308,10 +312,14 @@ static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) { check_session_reusage(ssl_fixture, &peer); check_alpn(ssl_fixture, &peer); check_security_level(&peer); - if (ssl_fixture->server_name_indication != nullptr) { - check_server1_peer(&peer); - } else { + if (ssl_fixture->server_name_indication == nullptr || + strcmp(ssl_fixture->server_name_indication, SSL_TSI_TEST_WRONG_SNI) == + 0) { + // Expect server to use default server0.pem. check_server0_peer(&peer); + } else { + // Expect server to use server1.pem. + check_server1_peer(&peer); } } else { GPR_ASSERT(ssl_fixture->base.client_result == nullptr); @@ -551,6 +559,19 @@ void ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain() { tsi_test_fixture_destroy(fixture); } +void ssl_tsi_test_do_handshake_with_wrong_server_name_indication() { + gpr_log(GPR_INFO, + "ssl_tsi_test_do_handshake_with_wrong_server_name_indication"); + /* server certs do not contain "test.google.cn". */ + tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); + ssl_tsi_test_fixture* ssl_fixture = + reinterpret_cast(fixture); + ssl_fixture->server_name_indication = + const_cast(SSL_TSI_TEST_WRONG_SNI); + tsi_test_do_handshake(fixture); + tsi_test_fixture_destroy(fixture); +} + void ssl_tsi_test_do_handshake_with_bad_server_cert() { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_bad_server_cert"); tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); @@ -638,10 +659,14 @@ void ssl_tsi_test_do_round_trip_for_all_configs() { void ssl_tsi_test_do_round_trip_odd_buffer_size() { gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_odd_buffer_size"); -#ifndef MEMORY_SANITIZER +#if !defined(MEMORY_SANITIZER) && !defined(GPR_ARCH_32) && !defined(__APPLE__) const size_t odd_sizes[] = {1025, 2051, 4103, 8207, 16409}; #else - // avoid test being extremely slow under MSAN + // 1. avoid test being extremely slow under MSAN + // 2. on 32-bit, the test is much slower (probably due to lack of boringssl + // asm optimizations) so we only run a subset of tests to avoid timeout + // 3. on Mac OS, we have slower testing machines so we only run a subset + // of tests to avoid timeout const size_t odd_sizes[] = {1025}; #endif const size_t size = sizeof(odd_sizes) / sizeof(size_t); @@ -915,6 +940,7 @@ int main(int argc, char** argv) { ssl_tsi_test_do_handshake_with_client_authentication_and_root_store(); ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain(); ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain(); + ssl_tsi_test_do_handshake_with_wrong_server_name_indication(); ssl_tsi_test_do_handshake_with_bad_server_cert(); ssl_tsi_test_do_handshake_with_bad_client_cert(); #ifdef OPENSSL_IS_BORINGSSL diff --git a/test/core/util/port_isolated_runtime_environment.cc b/test/core/util/port_isolated_runtime_environment.cc index 1f678c08e57..5e043e7f970 100644 --- a/test/core/util/port_isolated_runtime_environment.cc +++ b/test/core/util/port_isolated_runtime_environment.cc @@ -43,7 +43,7 @@ static int get_random_port_offset() { static int s_initial_offset = get_random_port_offset(); static gpr_atm s_pick_counter = 0; -int grpc_pick_unused_port_or_die(void) { +static int grpc_pick_unused_port_or_die_impl(void) { int orig_counter_val = static_cast(gpr_atm_full_fetch_add(&s_pick_counter, 1)); GPR_ASSERT(orig_counter_val < (MAX_PORT - MIN_PORT + 1)); @@ -51,6 +51,19 @@ int grpc_pick_unused_port_or_die(void) { (s_initial_offset + orig_counter_val) % (MAX_PORT - MIN_PORT + 1); } +int grpc_pick_unused_port_or_die(void) { + while (true) { + int port = grpc_pick_unused_port_or_die_impl(); + // 5985 cannot be bound on Windows RBE and results in + // WSA_ERROR 10013: "An attempt was made to access a socket in a way + // forbidden by its access permissions." + if (port == 5985) { + continue; + } + return port; + } +} + void grpc_recycle_unused_port(int port) { (void)port; } #endif /* GRPC_PORT_ISOLATED_RUNTIME */ diff --git a/test/cpp/client/BUILD b/test/cpp/client/BUILD index b895d99724f..011d937bcb8 100644 --- a/test/cpp/client/BUILD +++ b/test/cpp/client/BUILD @@ -34,6 +34,7 @@ grpc_cc_test( grpc_cc_test( name = "client_channel_stress_test", + size = "large", srcs = ["client_channel_stress_test.cc"], # TODO(jtattermusch): test fails frequently on Win RBE, but passes locally # reenable the tests once it works reliably on Win RBE. diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc index 5fcfc11cc4c..8e92d5373ad 100644 --- a/test/cpp/client/client_channel_stress_test.cc +++ b/test/cpp/client/client_channel_stress_test.cc @@ -35,6 +35,7 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" @@ -151,7 +152,7 @@ class ClientChannelStressTest { for (const auto& balancer_server : balancer_servers_) { // Select each address with probability of 0.8. if (std::rand() % 10 < 8) { - addresses.emplace_back(AddressData{balancer_server.port_, true, ""}); + addresses.emplace_back(AddressData{balancer_server.port_, ""}); } } std::shuffle(addresses.begin(), addresses.end(), @@ -213,13 +214,12 @@ class ClientChannelStressTest { struct AddressData { int port; - bool is_balancer; grpc::string balancer_name; }; - void SetNextResolution(const std::vector& address_data) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result; + static grpc_core::ServerAddressList CreateAddressListFromAddressDataList( + const std::vector& address_data) { + grpc_core::ServerAddressList addresses; for (const auto& addr : address_data) { char* lb_uri_str; gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port); @@ -227,20 +227,34 @@ class ClientChannelStressTest { GPR_ASSERT(lb_uri != nullptr); grpc_resolved_address address; GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); - std::vector args_to_add; - if (addr.is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), - const_cast(addr.balancer_name.c_str()))); - } - grpc_channel_args* args = grpc_channel_args_copy_and_add( - nullptr, args_to_add.data(), args_to_add.size()); - result.addresses.emplace_back(address.addr, address.len, args); + grpc_arg arg = + grpc_core::CreateGrpclbBalancerNameArg(addr.balancer_name.c_str()); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(nullptr, &arg, 1); + addresses.emplace_back(address.addr, address.len, args); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); } + return addresses; + } + + static grpc_core::Resolver::Result MakeResolverResult( + const std::vector& balancer_address_data) { + grpc_core::Resolver::Result result; + grpc_error* error = GRPC_ERROR_NONE; + result.service_config = grpc_core::ServiceConfig::Create( + "{\"loadBalancingConfig\":[{\"grpclb\":{}}]}", &error); + GPR_ASSERT(error == GRPC_ERROR_NONE); + grpc_core::ServerAddressList balancer_addresses = + CreateAddressListFromAddressDataList(balancer_address_data); + grpc_arg arg = CreateGrpclbBalancerAddressesArg(&balancer_addresses); + result.args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + return result; + } + + void SetNextResolution(const std::vector& address_data) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = MakeResolverResult(address_data); response_generator_->SetResponse(std::move(result)); } diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index 53b8de105f5..a1a0633e1f8 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -78,7 +78,7 @@ static void tls_server_authorization_check_callback( arg->target_name = gpr_strdup("callback_target_name"); arg->peer_cert = gpr_strdup("callback_peer_cert"); arg->status = GRPC_STATUS_OK; - arg->error_details = gpr_strdup("callback_error_details"); + arg->error_details->set_error_details("callback_error_details"); } class TestTlsServerAuthorizationCheck @@ -342,6 +342,7 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) { std::shared_ptr config( new TlsCredentialReloadConfig(test_credential_reload)); grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg(); + c_arg->error_details = new grpc_tls_error_details(); c_arg->context = nullptr; TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg); struct TlsKeyMaterialsConfig::PemKeyCertPair pair1 = {"private_key1", @@ -352,7 +353,6 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) { arg->set_key_materials("pem_root_certs", pair_list); arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); arg->set_error_details("error_details"); - const char* error_details_before_schedule = c_arg->error_details; int schedule_output = config->Schedule(arg); EXPECT_EQ(schedule_output, 0); @@ -372,11 +372,11 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigSchedule) { EXPECT_STREQ(arg->error_details().c_str(), "error_details"); // Cleanup. - gpr_free(const_cast(error_details_before_schedule)); delete c_arg->key_materials_config; if (c_arg->destroy_context != nullptr) { c_arg->destroy_context(c_arg->context); } + delete c_arg->error_details; delete c_arg; delete config->c_config(); } @@ -386,6 +386,7 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigCppToC) { new TestTlsCredentialReload()); TlsCredentialReloadConfig config(test_credential_reload); grpc_tls_credential_reload_arg c_arg; + c_arg.error_details = new grpc_tls_error_details(); c_arg.context = nullptr; c_arg.cb_user_data = static_cast(nullptr); grpc_tls_key_materials_config c_key_materials; @@ -407,7 +408,7 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigCppToC) { c_arg.key_materials_config = &c_key_materials; c_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; grpc::string test_error_details = "error_details"; - c_arg.error_details = test_error_details.c_str(); + c_arg.error_details->set_error_details(test_error_details.c_str()); grpc_tls_credential_reload_config* c_config = config.c_config(); c_arg.config = c_config; @@ -424,10 +425,12 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigCppToC) { EXPECT_STREQ(pair_list[1].private_key(), "private_key3"); EXPECT_STREQ(pair_list[1].cert_chain(), "cert_chain3"); EXPECT_EQ(c_arg.status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); - EXPECT_STREQ(c_arg.error_details, test_error_details.c_str()); + EXPECT_STREQ(c_arg.error_details->error_details().c_str(), + test_error_details.c_str()); // Cleanup. c_arg.destroy_context(c_arg.context); + delete c_arg.error_details; delete config.c_config(); } @@ -441,6 +444,7 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckArgCallback) { new grpc_tls_server_authorization_check_arg; c_arg->cb = tls_server_authorization_check_callback; c_arg->context = nullptr; + c_arg->error_details = new grpc_tls_error_details(); TlsServerAuthorizationCheckArg* arg = new TlsServerAuthorizationCheckArg(c_arg); arg->set_cb_user_data(nullptr); @@ -451,7 +455,6 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckArgCallback) { arg->set_error_details("error_details"); const char* target_name_before_callback = c_arg->target_name; const char* peer_cert_before_callback = c_arg->peer_cert; - const char* error_details_before_callback = c_arg->error_details; arg->OnServerAuthorizationCheckDoneCallback(); EXPECT_STREQ(static_cast(arg->cb_user_data()), "cb_user_data"); @@ -465,10 +468,9 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckArgCallback) { // Cleanup. gpr_free(const_cast(target_name_before_callback)); gpr_free(const_cast(peer_cert_before_callback)); - gpr_free(const_cast(error_details_before_callback)); gpr_free(const_cast(c_arg->target_name)); gpr_free(const_cast(c_arg->peer_cert)); - gpr_free(const_cast(c_arg->error_details)); + delete c_arg->error_details; delete arg; delete c_arg; } @@ -479,6 +481,7 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) { TlsServerAuthorizationCheckConfig config(test_server_authorization_check); grpc_tls_server_authorization_check_arg* c_arg = new grpc_tls_server_authorization_check_arg(); + c_arg->error_details = new grpc_tls_error_details(); c_arg->context = nullptr; TlsServerAuthorizationCheckArg* arg = new TlsServerAuthorizationCheckArg(c_arg); @@ -490,7 +493,6 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) { arg->set_error_details("error_details"); const char* target_name_before_schedule = c_arg->target_name; const char* peer_cert_before_schedule = c_arg->peer_cert; - const char* error_details_before_schedule = c_arg->error_details; int schedule_output = config.Schedule(arg); EXPECT_EQ(schedule_output, 1); @@ -505,10 +507,9 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigSchedule) { gpr_free(arg->cb_user_data()); gpr_free(const_cast(target_name_before_schedule)); gpr_free(const_cast(peer_cert_before_schedule)); - gpr_free(const_cast(error_details_before_schedule)); gpr_free(const_cast(c_arg->target_name)); gpr_free(const_cast(c_arg->peer_cert)); - gpr_free(const_cast(c_arg->error_details)); + delete c_arg->error_details; if (c_arg->destroy_context != nullptr) { c_arg->destroy_context(c_arg->context); } @@ -527,7 +528,8 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) { c_arg.target_name = "target_name"; c_arg.peer_cert = "peer_cert"; c_arg.status = GRPC_STATUS_UNAUTHENTICATED; - c_arg.error_details = "error_details"; + c_arg.error_details = new grpc_tls_error_details(); + c_arg.error_details->set_error_details("error_details"); c_arg.config = config.c_config(); c_arg.context = nullptr; int c_schedule_output = (c_arg.config)->Schedule(&c_arg); @@ -537,12 +539,13 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigCppToC) { EXPECT_STREQ(c_arg.target_name, "sync_target_name"); EXPECT_STREQ(c_arg.peer_cert, "sync_peer_cert"); EXPECT_EQ(c_arg.status, GRPC_STATUS_OK); - EXPECT_STREQ(c_arg.error_details, "sync_error_details"); + EXPECT_STREQ(c_arg.error_details->error_details().c_str(), + "sync_error_details"); // Cleanup. gpr_free(c_arg.cb_user_data); c_arg.destroy_context(c_arg.context); - gpr_free(const_cast(c_arg.error_details)); + delete c_arg.error_details; gpr_free(const_cast(c_arg.target_name)); gpr_free(const_cast(c_arg.peer_cert)); delete config.c_config(); @@ -587,7 +590,9 @@ TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) { c_options->key_materials_config(); c_credential_reload_arg.status = GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED; grpc::string test_error_details = "error_details"; - c_credential_reload_arg.error_details = test_error_details.c_str(); + c_credential_reload_arg.error_details = new grpc_tls_error_details(); + c_credential_reload_arg.error_details->set_error_details( + test_error_details.c_str()); c_credential_reload_arg.context = nullptr; grpc_tls_server_authorization_check_config* c_server_authorization_check_config = @@ -599,7 +604,9 @@ TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) { c_server_authorization_check_arg.target_name = "target_name"; c_server_authorization_check_arg.peer_cert = "peer_cert"; c_server_authorization_check_arg.status = GRPC_STATUS_UNAUTHENTICATED; - c_server_authorization_check_arg.error_details = "error_details"; + c_server_authorization_check_arg.error_details = new grpc_tls_error_details(); + c_server_authorization_check_arg.error_details->set_error_details( + "error_details"); c_server_authorization_check_arg.context = nullptr; EXPECT_STREQ(c_key_materials_config->pem_root_certs(), "pem_root_certs"); EXPECT_EQ( @@ -627,7 +634,7 @@ TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) { EXPECT_STREQ(c_pair_list[1].cert_chain(), "cert_chain3"); EXPECT_EQ(c_credential_reload_arg.status, GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW); - EXPECT_STREQ(c_credential_reload_arg.error_details, + EXPECT_STREQ(c_credential_reload_arg.error_details->error_details().c_str(), test_error_details.c_str()); int c_server_authorization_check_schedule_output = @@ -642,17 +649,19 @@ TEST_F(CredentialsTest, TlsCredentialsOptionsCppToC) { "sync_target_name"); EXPECT_STREQ(c_server_authorization_check_arg.peer_cert, "sync_peer_cert"); EXPECT_EQ(c_server_authorization_check_arg.status, GRPC_STATUS_OK); - EXPECT_STREQ(c_server_authorization_check_arg.error_details, - "sync_error_details"); + EXPECT_STREQ( + c_server_authorization_check_arg.error_details->error_details().c_str(), + "sync_error_details"); // Cleanup. c_credential_reload_arg.destroy_context(c_credential_reload_arg.context); + delete c_credential_reload_arg.error_details; c_server_authorization_check_arg.destroy_context( c_server_authorization_check_arg.context); gpr_free(c_server_authorization_check_arg.cb_user_data); gpr_free(const_cast(c_server_authorization_check_arg.target_name)); gpr_free(const_cast(c_server_authorization_check_arg.peer_cert)); - gpr_free(const_cast(c_server_authorization_check_arg.error_details)); + delete c_server_authorization_check_arg.error_details; delete c_options; } @@ -698,6 +707,7 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigErrorMessages) { std::shared_ptr config( new TlsCredentialReloadConfig(nullptr)); grpc_tls_credential_reload_arg* c_arg = new grpc_tls_credential_reload_arg; + c_arg->error_details = new grpc_tls_error_details(); c_arg->context = nullptr; TlsCredentialReloadArg* arg = new TlsCredentialReloadArg(c_arg); int schedule_output = config->Schedule(arg); @@ -706,7 +716,6 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigErrorMessages) { EXPECT_EQ(arg->status(), GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL); EXPECT_STREQ(arg->error_details().c_str(), "the interface of the credential reload config is nullptr"); - gpr_free(const_cast(c_arg->error_details)); arg->set_status(GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED); config->Cancel(arg); @@ -715,10 +724,10 @@ TEST_F(CredentialsTest, TlsCredentialReloadConfigErrorMessages) { "the interface of the credential reload config is nullptr"); // Cleanup. - gpr_free(const_cast(c_arg->error_details)); if (c_arg->destroy_context != nullptr) { c_arg->destroy_context(c_arg->context); } + delete c_arg->error_details; delete c_arg; delete config->c_config(); } @@ -728,6 +737,7 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) { new TlsServerAuthorizationCheckConfig(nullptr)); grpc_tls_server_authorization_check_arg* c_arg = new grpc_tls_server_authorization_check_arg; + c_arg->error_details = new grpc_tls_error_details(); c_arg->context = nullptr; TlsServerAuthorizationCheckArg* arg = new TlsServerAuthorizationCheckArg(c_arg); @@ -738,7 +748,6 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) { EXPECT_STREQ( arg->error_details().c_str(), "the interface of the server authorization check config is nullptr"); - gpr_free(const_cast(c_arg->error_details)); arg->set_status(GRPC_STATUS_OK); config->Cancel(arg); @@ -748,7 +757,7 @@ TEST_F(CredentialsTest, TlsServerAuthorizationCheckConfigErrorMessages) { "the interface of the server authorization check config is nullptr"); // Cleanup. - gpr_free(const_cast(c_arg->error_details)); + delete c_arg->error_details; if (c_arg->destroy_context != nullptr) { c_arg->destroy_context(c_arg->context); } diff --git a/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc b/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc index 7ba76f0da75..d4a942b9870 100644 --- a/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc +++ b/test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc @@ -37,6 +37,7 @@ #include #include +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" @@ -59,24 +60,21 @@ void TryConnectAndDestroy() { // The precise behavior is dependant on the test runtime environment though, // since connect() attempts on this address may unfortunately result in // "network unreachable" errors in some test runtime environments. - char* uri_str; - gpr_asprintf(&uri_str, "ipv6:[0100::1234]:443"); + const char* uri_str = "ipv6:[0100::1234]:443"; grpc_uri* lb_uri = grpc_uri_parse(uri_str, true); - gpr_free(uri_str); - GPR_ASSERT(lb_uri != nullptr); + ASSERT_NE(lb_uri, nullptr); grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); - std::vector address_args_to_add = { - grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1), - }; + ASSERT_TRUE(grpc_parse_uri(lb_uri, &address)); + grpc_uri_destroy(lb_uri); grpc_core::ServerAddressList addresses; - grpc_channel_args* address_args = grpc_channel_args_copy_and_add( - nullptr, address_args_to_add.data(), address_args_to_add.size()); - addresses.emplace_back(address.addr, address.len, address_args); + addresses.emplace_back(address.addr, address.len, nullptr); grpc_core::Resolver::Result lb_address_result; - lb_address_result.addresses = addresses; - grpc_uri_destroy(lb_uri); + grpc_error* error = GRPC_ERROR_NONE; + lb_address_result.service_config = grpc_core::ServiceConfig::Create( + "{\"loadBalancingConfig\":[{\"grpclb\":{}}]}", &error); + ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); + grpc_arg arg = grpc_core::CreateGrpclbBalancerAddressesArg(&addresses); + lb_address_result.args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); response_generator->SetResponse(lb_address_result); grpc::ChannelArguments args; args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, @@ -95,9 +93,9 @@ void TryConnectAndDestroy() { // unreachable balancer to begin. The connection should never become ready // because the LB we're trying to connect to is unreachable. channel->GetState(true /* try_to_connect */); - GPR_ASSERT( - !channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100))); - GPR_ASSERT("grpclb" == channel->GetLoadBalancingPolicyName()); + ASSERT_FALSE( + channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100))); + ASSERT_EQ("grpclb", channel->GetLoadBalancingPolicyName()); channel.reset(); }; diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index e6816f2f33c..7ad954d6d9a 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -839,7 +839,14 @@ class ServiceA final { public: WithStreamedUnaryMethod_MethodA1() { ::grpc::Service::MarkMethodStreamed(0, - new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2))); + new ::grpc::internal::StreamedUnaryHandler< + ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc_impl::ServerContext* context, + ::grpc_impl::ServerUnaryStreamer< + ::grpc::testing::Request, ::grpc::testing::Response>* streamer) { + return this->StreamedMethodA1(context, + streamer); + })); } ~WithStreamedUnaryMethod_MethodA1() override { BaseClassMustBeDerivedFromService(this); @@ -860,7 +867,14 @@ class ServiceA final { public: WithSplitStreamingMethod_MethodA3() { ::grpc::Service::MarkMethodStreamed(2, - new ::grpc::internal::SplitServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithSplitStreamingMethod_MethodA3::StreamedMethodA3, this, std::placeholders::_1, std::placeholders::_2))); + new ::grpc::internal::SplitServerStreamingHandler< + ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc_impl::ServerContext* context, + ::grpc_impl::ServerSplitStreamer< + ::grpc::testing::Request, ::grpc::testing::Response>* streamer) { + return this->StreamedMethodA3(context, + streamer); + })); } ~WithSplitStreamingMethod_MethodA3() override { BaseClassMustBeDerivedFromService(this); @@ -1129,7 +1143,14 @@ class ServiceB final { public: WithStreamedUnaryMethod_MethodB1() { ::grpc::Service::MarkMethodStreamed(0, - new ::grpc::internal::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2))); + new ::grpc::internal::StreamedUnaryHandler< + ::grpc::testing::Request, ::grpc::testing::Response>( + [this](::grpc_impl::ServerContext* context, + ::grpc_impl::ServerUnaryStreamer< + ::grpc::testing::Request, ::grpc::testing::Response>* streamer) { + return this->StreamedMethodB1(context, + streamer); + })); } ~WithStreamedUnaryMethod_MethodB1() override { BaseClassMustBeDerivedFromService(this); diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 885cae51ab4..a20128dcc2d 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -275,6 +275,7 @@ grpc_cc_test( grpc_cc_test( name = "end2end_test", size = "large", + flaky = True, # TODO(b/151704375) tags = ["no_test_ios"], deps = [ ":end2end_test_lib", @@ -438,6 +439,7 @@ grpc_cc_test( external_deps = [ "gtest", ], + flaky = True, # TODO(b/151315347) tags = ["no_windows"], # TODO(jtattermusch): fix test on windows deps = [ ":test_service_impl", diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index 79969f9c5e3..36c52b9798a 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -35,6 +35,7 @@ #include #include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" #include "src/core/ext/filters/client_channel/server_address.h" @@ -83,6 +84,13 @@ namespace grpc { namespace testing { namespace { +constexpr char kDefaultServiceConfig[] = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"grpclb\":{} }\n" + " ]\n" + "}"; + template class CountedService : public ServiceType { public: @@ -514,11 +522,10 @@ class GrpclbEnd2endTest : public ::testing::Test { struct AddressData { int port; - bool is_balancer; grpc::string balancer_name; }; - grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( + static grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList( const std::vector& address_data) { grpc_core::ServerAddressList addresses; for (const auto& addr : address_data) { @@ -528,16 +535,10 @@ class GrpclbEnd2endTest : public ::testing::Test { GPR_ASSERT(lb_uri != nullptr); grpc_resolved_address address; GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); - std::vector args_to_add; - if (addr.is_balancer) { - args_to_add.emplace_back(grpc_channel_arg_integer_create( - const_cast(GRPC_ARG_ADDRESS_IS_BALANCER), 1)); - args_to_add.emplace_back(grpc_channel_arg_string_create( - const_cast(GRPC_ARG_ADDRESS_BALANCER_NAME), - const_cast(addr.balancer_name.c_str()))); - } - grpc_channel_args* args = grpc_channel_args_copy_and_add( - nullptr, args_to_add.data(), args_to_add.size()); + grpc_arg arg = + grpc_core::CreateGrpclbBalancerNameArg(addr.balancer_name.c_str()); + grpc_channel_args* args = + grpc_channel_args_copy_and_add(nullptr, &arg, 1); addresses.emplace_back(address.addr, address.len, args); grpc_uri_destroy(lb_uri); gpr_free(lb_uri_str); @@ -545,34 +546,50 @@ class GrpclbEnd2endTest : public ::testing::Test { return addresses; } + static grpc_core::Resolver::Result MakeResolverResult( + const std::vector& balancer_address_data, + const std::vector& backend_address_data = {}, + const char* service_config_json = kDefaultServiceConfig) { + grpc_core::Resolver::Result result; + result.addresses = + CreateLbAddressesFromAddressDataList(backend_address_data); + grpc_error* error = GRPC_ERROR_NONE; + result.service_config = + grpc_core::ServiceConfig::Create(service_config_json, &error); + GPR_ASSERT(error == GRPC_ERROR_NONE); + grpc_core::ServerAddressList balancer_addresses = + CreateLbAddressesFromAddressDataList(balancer_address_data); + grpc_arg arg = CreateGrpclbBalancerAddressesArg(&balancer_addresses); + result.args = grpc_channel_args_copy_and_add(nullptr, &arg, 1); + return result; + } + void SetNextResolutionAllBalancers( - const char* service_config_json = nullptr) { + const char* service_config_json = kDefaultServiceConfig) { std::vector addresses; for (size_t i = 0; i < balancers_.size(); ++i) { - addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[i]->port_, ""}); } - SetNextResolution(addresses, service_config_json); + SetNextResolution(addresses, {}, service_config_json); } - void SetNextResolution(const std::vector& address_data, - const char* service_config_json = nullptr) { + void SetNextResolution( + const std::vector& balancer_address_data, + const std::vector& backend_address_data = {}, + const char* service_config_json = kDefaultServiceConfig) { grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result; - result.addresses = CreateLbAddressesFromAddressDataList(address_data); - if (service_config_json != nullptr) { - grpc_error* error = GRPC_ERROR_NONE; - result.service_config = - grpc_core::ServiceConfig::Create(service_config_json, &error); - GRPC_ERROR_UNREF(error); - } + grpc_core::Resolver::Result result = MakeResolverResult( + balancer_address_data, backend_address_data, service_config_json); response_generator_->SetResponse(std::move(result)); } void SetNextReresolutionResponse( - const std::vector& address_data) { + const std::vector& balancer_address_data, + const std::vector& backend_address_data = {}, + const char* service_config_json = kDefaultServiceConfig) { grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result; - result.addresses = CreateLbAddressesFromAddressDataList(address_data); + grpc_core::Resolver::Result result = MakeResolverResult( + balancer_address_data, backend_address_data, service_config_json); response_generator_->SetReresolutionResponse(std::move(result)); } @@ -747,44 +764,11 @@ TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfig) { EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } -TEST_F(SingleBalancerTest, - DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTest) { - const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - SetNextResolution({AddressData{backends_[0]->port_, false, ""}, - AddressData{balancers_[0]->port_, true, ""}}, - "{\n" - " \"loadBalancingConfig\":[\n" - " {\"pick_first\":{} }\n" - " ]\n" - "}"); - CheckRpcSendOk(); - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); -} - -TEST_F( - SingleBalancerTest, - DoNotSpecialCaseUseGrpclbWithLoadBalancingConfigTestAndNoBackendAddress) { - const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - SetNextResolution({AddressData{balancers_[0]->port_, true, ""}}, - "{\n" - " \"loadBalancingConfig\":[\n" - " {\"pick_first\":{} }\n" - " ]\n" - "}"); - // This should fail since we do not have a non-balancer backend - CheckRpcSendFailure(); - // Check LB policy name for the channel. - EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); -} - TEST_F(SingleBalancerTest, SelectGrpclbWithMigrationServiceConfigAndNoAddresses) { const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); - SetNextResolution({}, + SetNextResolution({}, {}, "{\n" " \"loadBalancingConfig\":[\n" " { \"does_not_exist\":{} },\n" @@ -804,23 +788,6 @@ TEST_F(SingleBalancerTest, EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); } -TEST_F(SingleBalancerTest, - SelectGrpclbWithMigrationServiceConfigAndNoBalancerAddresses) { - const int kFallbackTimeoutMs = 200 * grpc_test_slowdown_factor(); - ResetStub(kFallbackTimeoutMs); - // Resolution includes fallback address but no balancers. - SetNextResolution({AddressData{backends_[0]->port_, false, ""}}, - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"does_not_exist\":{} },\n" - " { \"grpclb\":{} }\n" - " ]\n" - "}"); - CheckRpcSendOk(1, 1000 /* timeout_ms */, true /* wait_for_ready */); - // Check LB policy name for the channel. - EXPECT_EQ("grpclb", channel_->GetLoadBalancingPolicyName()); -} - TEST_F(SingleBalancerTest, UsePickFirstChildPolicy) { SetNextResolutionAllBalancers( "{\n" @@ -875,7 +842,7 @@ TEST_F(SingleBalancerTest, SwapChildPolicy) { EXPECT_EQ(backends_[i]->service_.request_count(), 0UL); } // Send new resolution that removes child policy from service config. - SetNextResolutionAllBalancers("{}"); + SetNextResolutionAllBalancers(); WaitForAllBackends(); CheckRpcSendOk(kNumRpcs, 1000 /* timeout_ms */, true /* wait_for_ready */); // Check that every backend saw the same number of requests. This verifies @@ -903,9 +870,11 @@ TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { SetNextResolution( { // Unreachable balancer. - {unreachable_balancer_port, true, ""}, + {unreachable_balancer_port, ""}, + }, + { // Fallback address: first backend. - {backends_[0]->port_, false, ""}, + {backends_[0]->port_, ""}, }, "{\n" " \"loadBalancingConfig\":[\n" @@ -923,9 +892,11 @@ TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { SetNextResolution( { // Unreachable balancer. - {unreachable_balancer_port, true, ""}, + {unreachable_balancer_port, ""}, + }, + { // Fallback address: unreachable backend. - {unreachable_backend_port, false, ""}, + {unreachable_backend_port, ""}, }, "{\n" " \"loadBalancingConfig\":[\n" @@ -946,10 +917,12 @@ TEST_F(SingleBalancerTest, UpdatesGoToMostRecentChildPolicy) { SetNextResolution( { // Unreachable balancer. - {unreachable_balancer_port, true, ""}, + {unreachable_balancer_port, ""}, + }, + { // Fallback address: second and third backends. - {backends_[1]->port_, false, ""}, - {backends_[2]->port_, false, ""}, + {backends_[1]->port_, ""}, + {backends_[2]->port_, ""}, }, "{\n" " \"loadBalancingConfig\":[\n" @@ -988,7 +961,7 @@ TEST_F(SingleBalancerTest, SameBackendListedMultipleTimes) { TEST_F(SingleBalancerTest, SecureNaming) { ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution({AddressData{balancers_[0]->port_, true, "lb"}}); + SetNextResolution({AddressData{balancers_[0]->port_, "lb"}}); const size_t kNumRpcsPerAddress = 100; ScheduleResponseForBalancer( 0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}), @@ -1020,7 +993,7 @@ TEST_F(SingleBalancerTest, SecureNamingDeathTest) { ASSERT_DEATH_IF_SUPPORTED( { ResetStub(0, kApplicationTargetName_ + ";lb"); - SetNextResolution({AddressData{balancers_[0]->port_, true, "woops"}}); + SetNextResolution({AddressData{balancers_[0]->port_, "woops"}}); channel_->WaitForConnected(grpc_timeout_seconds_to_deadline(1)); }, ""); @@ -1080,12 +1053,13 @@ TEST_F(SingleBalancerTest, Fallback) { const size_t kNumBackendsInResolution = backends_.size() / 2; ResetStub(kFallbackTimeoutMs); - std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + std::vector balancer_addresses; + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + std::vector backend_addresses; for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); } - SetNextResolution(addresses); + SetNextResolution(balancer_addresses, backend_addresses); // Send non-empty serverlist only after kServerlistDelayMs. ScheduleResponseForBalancer( @@ -1148,12 +1122,13 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { const size_t kNumBackendsInResolutionUpdate = backends_.size() / 3; ResetStub(kFallbackTimeoutMs); - std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + std::vector balancer_addresses; + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + std::vector backend_addresses; for (size_t i = 0; i < kNumBackendsInResolution; ++i) { - addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); } - SetNextResolution(addresses); + SetNextResolution(balancer_addresses, backend_addresses); // Send non-empty serverlist only after kServerlistDelayMs. ScheduleResponseForBalancer( @@ -1183,13 +1158,14 @@ TEST_F(SingleBalancerTest, FallbackUpdate) { EXPECT_EQ(0U, backends_[i]->service_.request_count()); } - addresses.clear(); - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + balancer_addresses.clear(); + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + backend_addresses.clear(); for (size_t i = kNumBackendsInResolution; i < kNumBackendsInResolution + kNumBackendsInResolutionUpdate; ++i) { - addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); } - SetNextResolution(addresses); + SetNextResolution(balancer_addresses, backend_addresses); // Wait until the resolution update has been processed and all the new // fallback backends are reachable. @@ -1253,14 +1229,15 @@ TEST_F(SingleBalancerTest, // First two backends are fallback, last two are pointed to by balancer. const size_t kNumFallbackBackends = 2; const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; - std::vector addresses; + std::vector backend_addresses; for (size_t i = 0; i < kNumFallbackBackends; ++i) { - addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); } + std::vector balancer_addresses; for (size_t i = 0; i < balancers_.size(); ++i) { - addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + balancer_addresses.emplace_back(AddressData{balancers_[i]->port_, ""}); } - SetNextResolution(addresses); + SetNextResolution(balancer_addresses, backend_addresses); ScheduleResponseForBalancer(0, BalancerServiceImpl::BuildResponseForBackends( GetBackendPorts(kNumFallbackBackends), {}), @@ -1307,14 +1284,15 @@ TEST_F(SingleBalancerTest, // First two backends are fallback, last two are pointed to by balancer. const size_t kNumFallbackBackends = 2; const size_t kNumBalancerBackends = backends_.size() - kNumFallbackBackends; - std::vector addresses; + std::vector backend_addresses; for (size_t i = 0; i < kNumFallbackBackends; ++i) { - addresses.emplace_back(AddressData{backends_[i]->port_, false, ""}); + backend_addresses.emplace_back(AddressData{backends_[i]->port_, ""}); } + std::vector balancer_addresses; for (size_t i = 0; i < balancers_.size(); ++i) { - addresses.emplace_back(AddressData{balancers_[i]->port_, true, ""}); + balancer_addresses.emplace_back(AddressData{balancers_[i]->port_, ""}); } - SetNextResolution(addresses); + SetNextResolution(balancer_addresses, backend_addresses); ScheduleResponseForBalancer(0, BalancerServiceImpl::BuildResponseForBackends( GetBackendPorts(kNumFallbackBackends), {}), @@ -1358,10 +1336,12 @@ TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerChannelFails) { const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); // Return an unreachable balancer and one fallback backend. - std::vector addresses; - addresses.emplace_back(AddressData{grpc_pick_unused_port_or_die(), true, ""}); - addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); - SetNextResolution(addresses); + std::vector balancer_addresses; + balancer_addresses.emplace_back( + AddressData{grpc_pick_unused_port_or_die(), ""}); + std::vector backend_addresses; + backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); + SetNextResolution(balancer_addresses, backend_addresses); // Send RPC with deadline less than the fallback timeout and make sure it // succeeds. CheckRpcSendOk(/* times */ 1, /* timeout_ms */ 1000, @@ -1372,10 +1352,11 @@ TEST_F(SingleBalancerTest, FallbackEarlyWhenBalancerCallFails) { const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); // Return one balancer and one fallback backend. - std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); - SetNextResolution(addresses); + std::vector balancer_addresses; + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + std::vector backend_addresses; + backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); + SetNextResolution(balancer_addresses, backend_addresses); // Balancer drops call without sending a serverlist. balancers_[0]->service_.NotifyDoneWithServerlists(); // Send RPC with deadline less than the fallback timeout and make sure it @@ -1388,10 +1369,11 @@ TEST_F(SingleBalancerTest, FallbackControlledByBalancer_BeforeFirstServerlist) { const int kFallbackTimeoutMs = 10000 * grpc_test_slowdown_factor(); ResetStub(kFallbackTimeoutMs); // Return one balancer and one fallback backend. - std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); - SetNextResolution(addresses); + std::vector balancer_addresses; + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + std::vector backend_addresses; + backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); + SetNextResolution(balancer_addresses, backend_addresses); // Balancer explicitly tells client to fallback. LoadBalanceResponse resp; resp.mutable_fallback_response(); @@ -1404,10 +1386,11 @@ TEST_F(SingleBalancerTest, FallbackControlledByBalancer_BeforeFirstServerlist) { TEST_F(SingleBalancerTest, FallbackControlledByBalancer_AfterFirstServerlist) { // Return one balancer and one fallback backend (backend 0). - std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); - SetNextResolution(addresses); + std::vector balancer_addresses; + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + std::vector backend_addresses; + backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); + SetNextResolution(balancer_addresses, backend_addresses); // Balancer initially sends serverlist, then tells client to fall back, // then sends the serverlist again. // The serverlist points to backend 1. @@ -1483,7 +1466,7 @@ TEST_F(UpdatesTest, UpdateBalancersButKeepUsingOriginalBalancer) { EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector addresses; - addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); @@ -1542,9 +1525,9 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { EXPECT_EQ(0U, balancers_[2]->service_.response_count()); std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); - addresses.emplace_back(AddressData{balancers_[2]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); + addresses.emplace_back(AddressData{balancers_[2]->port_, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); @@ -1562,8 +1545,8 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { balancers_[0]->service_.NotifyDoneWithServerlists(); addresses.clear(); - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); @@ -1583,7 +1566,7 @@ TEST_F(UpdatesTest, UpdateBalancersRepeated) { TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); SetNextResolution(addresses); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; @@ -1623,7 +1606,7 @@ TEST_F(UpdatesTest, UpdateBalancersDeadUpdate) { EXPECT_EQ(0U, balancers_[2]->service_.response_count()); addresses.clear(); - addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); SetNextResolution(addresses); gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); @@ -1660,18 +1643,20 @@ TEST_F(UpdatesTest, ReresolveDeadBackend) { ResetStub(500); // The first resolution contains the addresses of a balancer that never // responds, and a fallback backend. - std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - addresses.emplace_back(AddressData{backends_[0]->port_, false, ""}); - SetNextResolution(addresses); + std::vector balancer_addresses; + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + std::vector backend_addresses; + backend_addresses.emplace_back(AddressData{backends_[0]->port_, ""}); + SetNextResolution(balancer_addresses, backend_addresses); // Ask channel to connect to trigger resolver creation. channel_->GetState(true); // The re-resolution result will contain the addresses of the same balancer // and a new fallback backend. - addresses.clear(); - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); - addresses.emplace_back(AddressData{backends_[1]->port_, false, ""}); - SetNextReresolutionResponse(addresses); + balancer_addresses.clear(); + balancer_addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); + backend_addresses.clear(); + backend_addresses.emplace_back(AddressData{backends_[1]->port_, ""}); + SetNextReresolutionResponse(balancer_addresses, backend_addresses); // Start servers and send 10 RPCs per server. gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); @@ -1720,10 +1705,10 @@ TEST_F(UpdatesWithClientLoadReportingTest, ReresolveDeadBalancer) { // Ask channel to connect to trigger resolver creation. channel_->GetState(true); std::vector addresses; - addresses.emplace_back(AddressData{balancers_[0]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[0]->port_, ""}); SetNextResolution(addresses); addresses.clear(); - addresses.emplace_back(AddressData{balancers_[1]->port_, true, ""}); + addresses.emplace_back(AddressData{balancers_[1]->port_, ""}); SetNextReresolutionResponse(addresses); const std::vector first_backend{GetBackendPorts()[0]}; const std::vector second_backend{GetBackendPorts()[1]}; diff --git a/test/cpp/end2end/nonblocking_test.cc b/test/cpp/end2end/nonblocking_test.cc index eb651df21df..4be070ec717 100644 --- a/test/cpp/end2end/nonblocking_test.cc +++ b/test/cpp/end2end/nonblocking_test.cc @@ -39,14 +39,18 @@ #ifdef GRPC_POSIX_SOCKET // Thread-local variable to so that only polls from this test assert -// non-blocking (not polls from resolver, timer thread, etc) -GPR_TLS_DECL(g_is_nonblocking_test); +// non-blocking (not polls from resolver, timer thread, etc), and only when the +// thread is waiting on polls caused by CompletionQueue::AsyncNext (not for +// picking a port or other reasons). +GPR_TLS_DECL(g_is_nonblocking_poll); namespace { int maybe_assert_non_blocking_poll(struct pollfd* pfds, nfds_t nfds, int timeout) { - if (gpr_tls_get(&g_is_nonblocking_test)) { + // Only assert that this poll should have zero timeout if we're in the + // middle of a zero-timeout CQ Next. + if (gpr_tls_get(&g_is_nonblocking_poll)) { GPR_ASSERT(timeout == 0); } return poll(pfds, nfds, timeout); @@ -74,11 +78,17 @@ class NonblockingTest : public ::testing::Test { } bool LoopForTag(void** tag, bool* ok) { + // Temporarily set the thread-local nonblocking poll flag so that the polls + // caused by this loop are indeed sent by the library with zero timeout. + intptr_t orig_val = gpr_tls_get(&g_is_nonblocking_poll); + gpr_tls_set(&g_is_nonblocking_poll, static_cast(true)); for (;;) { auto r = cq_->AsyncNext(tag, ok, gpr_time_0(GPR_CLOCK_REALTIME)); if (r == CompletionQueue::SHUTDOWN) { + gpr_tls_set(&g_is_nonblocking_poll, orig_val); return false; } else if (r == CompletionQueue::GOT_EVENT) { + gpr_tls_set(&g_is_nonblocking_poll, orig_val); return true; } } @@ -185,10 +195,20 @@ int main(int argc, char** argv) { #ifdef GRPC_POSIX_SOCKET // Override the poll function before anything else can happen grpc_poll_function = maybe_assert_non_blocking_poll; -#endif // GRPC_POSIX_SOCKET grpc::testing::TestEnvironment env(argc, argv); ::testing::InitGoogleTest(&argc, argv); + gpr_tls_init(&g_is_nonblocking_poll); + + // Start the nonblocking poll thread-local variable as false because the + // thread that issues RPCs starts by picking a port (which has non-zero + // timeout). + gpr_tls_set(&g_is_nonblocking_poll, static_cast(false)); + int ret = RUN_ALL_TESTS(); + gpr_tls_destroy(&g_is_nonblocking_poll); return ret; +#else // GRPC_POSIX_SOCKET + return 0; +#endif // GRPC_POSIX_SOCKET } diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index a710f24510e..803af0dd346 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -22,7 +22,9 @@ #include #include #include +#include #include +#include #include #include @@ -296,8 +298,9 @@ class ClientStats { }; // Converts from proto message class. - ClientStats(const ClusterStats& cluster_stats) - : total_dropped_requests_(cluster_stats.total_dropped_requests()) { + explicit ClientStats(const ClusterStats& cluster_stats) + : cluster_name_(cluster_stats.cluster_name()), + total_dropped_requests_(cluster_stats.total_dropped_requests()) { for (const auto& input_locality_stats : cluster_stats.upstream_locality_stats()) { locality_stats_.emplace(input_locality_stats.locality().sub_zone(), @@ -310,6 +313,11 @@ class ClientStats { } } + const std::string& cluster_name() const { return cluster_name_; } + + const std::map& locality_stats() const { + return locality_stats_; + } uint64_t total_successful_requests() const { uint64_t sum = 0; for (auto& p : locality_stats_) { @@ -338,7 +346,9 @@ class ClientStats { } return sum; } + uint64_t total_dropped_requests() const { return total_dropped_requests_; } + uint64_t dropped_requests(const grpc::string& category) const { auto iter = dropped_requests_.find(category); GPR_ASSERT(iter != dropped_requests_.end()); @@ -346,6 +356,7 @@ class ClientStats { } private: + std::string cluster_name_; std::map locality_stats_; uint64_t total_dropped_requests_; std::map dropped_requests_; @@ -391,41 +402,6 @@ class AdsServiceImpl : public AggregatedDiscoveryService::Service, }; using Stream = ServerReaderWriter; - using ResponseDelayPair = std::pair; - - // A queue of resource type/name pairs that have changed since the client - // subscribed to them. - using UpdateQueue = std::deque< - std::pair>; - - // A struct representing a client's subscription to a particular resource. - struct SubscriptionState { - // Version that the client currently knows about. - int current_version = 0; - // The queue upon which to place updates when the resource is updated. - UpdateQueue* update_queue; - }; - - // A struct representing the a client's subscription to all the resources. - using SubscriptionNameMap = - std::map; - using SubscriptionMap = - std::map; - - // A struct representing the current state for a resource: - // - the version of the resource that is set by the SetResource() methods. - // - a list of subscriptions interested in this resource. - struct ResourceState { - int version = 0; - absl::optional resource; - std::set subscriptions; - }; - - // A struct representing the current state for all resources: - // LDS, CDS, EDS, and RDS for the class as a whole. - using ResourceNameMap = - std::map; - using ResourceMap = std::map; AdsServiceImpl(bool enable_load_reporting) { // Construct RDS response data. @@ -452,121 +428,15 @@ class AdsServiceImpl : public AggregatedDiscoveryService::Service, SetCdsResource(default_cluster_, kDefaultResourceName); } - // Starting a thread to do blocking read on the stream until cancel. - void BlockingRead(Stream* stream, std::deque* requests, - bool* stream_closed) { - DiscoveryRequest request; - bool seen_first_request = false; - while (stream->Read(&request)) { - if (!seen_first_request) { - EXPECT_TRUE(request.has_node()); - ASSERT_FALSE(request.node().client_features().empty()); - EXPECT_EQ(request.node().client_features(0), - "envoy.lb.does_not_support_overprovisioning"); - seen_first_request = true; - } - { - grpc_core::MutexLock lock(&ads_mu_); - requests->emplace_back(std::move(request)); - } - } - gpr_log(GPR_INFO, "ADS[%p]: Null read, stream closed", this); - grpc_core::MutexLock lock(&ads_mu_); - *stream_closed = true; - } - - // Checks whether the client needs to receive a newer version of - // the resource. If so, updates subscription_state->current_version and - // returns true. - bool ClientNeedsResourceUpdate(const ResourceState& resource_state, - SubscriptionState* subscription_state) { - if (subscription_state->current_version < resource_state.version) { - subscription_state->current_version = resource_state.version; - return true; - } - return false; - } - - // Subscribes to a resource if not already subscribed: - // 1. Sets the update_queue field in subscription_state. - // 2. Adds subscription_state to resource_state->subscriptions. - void MaybeSubscribe(const std::string& resource_type, - const std::string& resource_name, - SubscriptionState* subscription_state, - ResourceState* resource_state, - UpdateQueue* update_queue) { - // The update_queue will be null if we were not previously subscribed. - if (subscription_state->update_queue != nullptr) return; - subscription_state->update_queue = update_queue; - resource_state->subscriptions.emplace(subscription_state); - gpr_log(GPR_INFO, "ADS[%p]: subscribe to resource type %s name %s state %p", - this, resource_type.c_str(), resource_name.c_str(), - &subscription_state); - } - - // Removes subscriptions for resources no longer present in the - // current request. - void ProcessUnsubscriptions( - const std::string& resource_type, - const std::set& resources_in_current_request, - SubscriptionNameMap* subscription_name_map, - ResourceNameMap* resource_name_map) { - for (auto it = subscription_name_map->begin(); - it != subscription_name_map->end();) { - const std::string& resource_name = it->first; - SubscriptionState& subscription_state = it->second; - if (resources_in_current_request.find(resource_name) != - resources_in_current_request.end()) { - ++it; - continue; - } - gpr_log(GPR_INFO, "ADS[%p]: Unsubscribe to type=%s name=%s state=%p", - this, resource_type.c_str(), resource_name.c_str(), - &subscription_state); - auto resource_it = resource_name_map->find(resource_name); - GPR_ASSERT(resource_it != resource_name_map->end()); - auto& resource_state = resource_it->second; - resource_state.subscriptions.erase(&subscription_state); - if (resource_state.subscriptions.empty() && - !resource_state.resource.has_value()) { - resource_name_map->erase(resource_it); - } - it = subscription_name_map->erase(it); - } - } - - // Completing the building a DiscoveryResponse by adding common information - // for all resources and by adding all subscribed resources for LDS and CDS. - void CompleteBuildingDiscoveryResponse( - const std::string& resource_type, const int version, - const SubscriptionNameMap& subscription_name_map, - const std::set& resources_added_to_response, - DiscoveryResponse* response) { - resource_type_response_state_[resource_type] = SENT; - response->set_type_url(resource_type); - response->set_version_info(absl::StrCat(version)); - response->set_nonce(absl::StrCat(version)); - if (resource_type == kLdsTypeUrl || resource_type == kCdsTypeUrl) { - // For LDS and CDS we must send back all subscribed resources - // (even the unchanged ones) - for (const auto& p : subscription_name_map) { - const std::string& resource_name = p.first; - if (resources_added_to_response.find(resource_name) == - resources_added_to_response.end()) { - const ResourceState& resource_state = - resource_map_[resource_type][resource_name]; - if (resource_state.resource.has_value()) { - response->add_resources()->CopyFrom( - resource_state.resource.value()); - } - } - } - } - } - Status StreamAggregatedResources(ServerContext* context, Stream* stream) override { gpr_log(GPR_INFO, "ADS[%p]: StreamAggregatedResources starts", this); + // Resources (type/name pairs) that have changed since the client + // subscribed to them. + UpdateQueue update_queue; + // Resources that the client will be subscribed to keyed by resource type + // url. + SubscriptionMap subscription_map; [&]() { { grpc_core::MutexLock lock(&ads_mu_); @@ -575,12 +445,6 @@ class AdsServiceImpl : public AggregatedDiscoveryService::Service, // Balancer shouldn't receive the call credentials metadata. EXPECT_EQ(context->client_metadata().find(g_kCallCredsMdKey), context->client_metadata().end()); - // Resources (type/name pairs) that have changed since the client - // subscribed to them. - UpdateQueue update_queue; - // Resources that the client will be subscribed to keyed by resource type - // url. - SubscriptionMap subscription_map; // Current Version map keyed by resource type url. std::map resource_type_version; // Creating blocking thread to read from stream. @@ -732,6 +596,21 @@ class AdsServiceImpl : public AggregatedDiscoveryService::Service, } reader.join(); }(); + // Clean up any subscriptions that were still active when the call finished. + { + grpc_core::MutexLock lock(&ads_mu_); + for (auto& p : subscription_map) { + const std::string& type_url = p.first; + SubscriptionNameMap& subscription_name_map = p.second; + for (auto& q : subscription_name_map) { + const std::string& resource_name = q.first; + SubscriptionState& subscription_state = q.second; + ResourceState& resource_state = + resource_map_[type_url][resource_name]; + resource_state.subscriptions.erase(&subscription_state); + } + } + } gpr_log(GPR_INFO, "ADS[%p]: StreamAggregatedResources done", this); return Status::OK; } @@ -847,7 +726,6 @@ class AdsServiceImpl : public AggregatedDiscoveryService::Service, { grpc_core::MutexLock lock(&ads_mu_); NotifyDoneWithAdsCallLocked(); - resource_map_.clear(); resource_type_response_state_.clear(); } gpr_log(GPR_INFO, "ADS[%p]: shut down", this); @@ -908,6 +786,152 @@ class AdsServiceImpl : public AggregatedDiscoveryService::Service, } private: + // A queue of resource type/name pairs that have changed since the client + // subscribed to them. + using UpdateQueue = std::deque< + std::pair>; + + // A struct representing a client's subscription to a particular resource. + struct SubscriptionState { + // Version that the client currently knows about. + int current_version = 0; + // The queue upon which to place updates when the resource is updated. + UpdateQueue* update_queue; + }; + + // A struct representing the a client's subscription to all the resources. + using SubscriptionNameMap = + std::map; + using SubscriptionMap = + std::map; + + // A struct representing the current state for a resource: + // - the version of the resource that is set by the SetResource() methods. + // - a list of subscriptions interested in this resource. + struct ResourceState { + int version = 0; + absl::optional resource; + std::set subscriptions; + }; + + // A struct representing the current state for all resources: + // LDS, CDS, EDS, and RDS for the class as a whole. + using ResourceNameMap = + std::map; + using ResourceMap = std::map; + + // Starting a thread to do blocking read on the stream until cancel. + void BlockingRead(Stream* stream, std::deque* requests, + bool* stream_closed) { + DiscoveryRequest request; + bool seen_first_request = false; + while (stream->Read(&request)) { + if (!seen_first_request) { + EXPECT_TRUE(request.has_node()); + ASSERT_FALSE(request.node().client_features().empty()); + EXPECT_EQ(request.node().client_features(0), + "envoy.lb.does_not_support_overprovisioning"); + seen_first_request = true; + } + { + grpc_core::MutexLock lock(&ads_mu_); + requests->emplace_back(std::move(request)); + } + } + gpr_log(GPR_INFO, "ADS[%p]: Null read, stream closed", this); + grpc_core::MutexLock lock(&ads_mu_); + *stream_closed = true; + } + + // Checks whether the client needs to receive a newer version of + // the resource. If so, updates subscription_state->current_version and + // returns true. + bool ClientNeedsResourceUpdate(const ResourceState& resource_state, + SubscriptionState* subscription_state) { + if (subscription_state->current_version < resource_state.version) { + subscription_state->current_version = resource_state.version; + return true; + } + return false; + } + + // Subscribes to a resource if not already subscribed: + // 1. Sets the update_queue field in subscription_state. + // 2. Adds subscription_state to resource_state->subscriptions. + void MaybeSubscribe(const std::string& resource_type, + const std::string& resource_name, + SubscriptionState* subscription_state, + ResourceState* resource_state, + UpdateQueue* update_queue) { + // The update_queue will be null if we were not previously subscribed. + if (subscription_state->update_queue != nullptr) return; + subscription_state->update_queue = update_queue; + resource_state->subscriptions.emplace(subscription_state); + gpr_log(GPR_INFO, "ADS[%p]: subscribe to resource type %s name %s state %p", + this, resource_type.c_str(), resource_name.c_str(), + &subscription_state); + } + + // Removes subscriptions for resources no longer present in the + // current request. + void ProcessUnsubscriptions( + const std::string& resource_type, + const std::set& resources_in_current_request, + SubscriptionNameMap* subscription_name_map, + ResourceNameMap* resource_name_map) { + for (auto it = subscription_name_map->begin(); + it != subscription_name_map->end();) { + const std::string& resource_name = it->first; + SubscriptionState& subscription_state = it->second; + if (resources_in_current_request.find(resource_name) != + resources_in_current_request.end()) { + ++it; + continue; + } + gpr_log(GPR_INFO, "ADS[%p]: Unsubscribe to type=%s name=%s state=%p", + this, resource_type.c_str(), resource_name.c_str(), + &subscription_state); + auto resource_it = resource_name_map->find(resource_name); + GPR_ASSERT(resource_it != resource_name_map->end()); + auto& resource_state = resource_it->second; + resource_state.subscriptions.erase(&subscription_state); + if (resource_state.subscriptions.empty() && + !resource_state.resource.has_value()) { + resource_name_map->erase(resource_it); + } + it = subscription_name_map->erase(it); + } + } + + // Completing the building a DiscoveryResponse by adding common information + // for all resources and by adding all subscribed resources for LDS and CDS. + void CompleteBuildingDiscoveryResponse( + const std::string& resource_type, const int version, + const SubscriptionNameMap& subscription_name_map, + const std::set& resources_added_to_response, + DiscoveryResponse* response) { + resource_type_response_state_[resource_type] = SENT; + response->set_type_url(resource_type); + response->set_version_info(absl::StrCat(version)); + response->set_nonce(absl::StrCat(version)); + if (resource_type == kLdsTypeUrl || resource_type == kCdsTypeUrl) { + // For LDS and CDS we must send back all subscribed resources + // (even the unchanged ones) + for (const auto& p : subscription_name_map) { + const std::string& resource_name = p.first; + if (resources_added_to_response.find(resource_name) == + resources_added_to_response.end()) { + const ResourceState& resource_state = + resource_map_[resource_type][resource_name]; + if (resource_state.resource.has_value()) { + response->add_resources()->CopyFrom( + resource_state.resource.value()); + } + } + } + } + } + grpc_core::CondVar ads_cond_; // Protect the members below. grpc_core::Mutex ads_mu_; @@ -933,60 +957,62 @@ class LrsServiceImpl : public LrsService, explicit LrsServiceImpl(int client_load_reporting_interval_seconds) : client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds) {} + client_load_reporting_interval_seconds), + cluster_names_({kDefaultResourceName}) {} Status StreamLoadStats(ServerContext* /*context*/, Stream* stream) override { gpr_log(GPR_INFO, "LRS[%p]: StreamLoadStats starts", this); + GPR_ASSERT(client_load_reporting_interval_seconds_ > 0); // Take a reference of the LrsServiceImpl object, reference will go // out of scope after this method exits. std::shared_ptr lrs_service_impl = shared_from_this(); - // Read request. + // Read initial request. LoadStatsRequest request; if (stream->Read(&request)) { - if (client_load_reporting_interval_seconds_ > 0) { - IncreaseRequestCount(); - // Send response. - LoadStatsResponse response; - std::string server_name; - auto it = request.node().metadata().fields().find( - "PROXYLESS_CLIENT_HOSTNAME"); - if (it != request.node().metadata().fields().end()) { - server_name = it->second.string_value(); - } - GPR_ASSERT(server_name != ""); - response.add_clusters(server_name); - response.mutable_load_reporting_interval()->set_seconds( - client_load_reporting_interval_seconds_); - stream->Write(response); - IncreaseResponseCount(); - // Wait for report. - request.Clear(); - if (stream->Read(&request)) { - gpr_log(GPR_INFO, "LRS[%p]: received client load report message '%s'", - this, request.DebugString().c_str()); - GPR_ASSERT(request.cluster_stats().size() == 1); - const ClusterStats& cluster_stats = request.cluster_stats()[0]; - // We need to acquire the lock here in order to prevent the notify_one - // below from firing before its corresponding wait is executed. - grpc_core::MutexLock lock(&load_report_mu_); - GPR_ASSERT(client_stats_ == nullptr); - client_stats_.reset(new ClientStats(cluster_stats)); - load_report_ready_ = true; - load_report_cond_.Signal(); + IncreaseRequestCount(); // Only for initial request. + // Verify server name set in metadata. + auto it = + request.node().metadata().fields().find("PROXYLESS_CLIENT_HOSTNAME"); + GPR_ASSERT(it != request.node().metadata().fields().end()); + EXPECT_EQ(it->second.string_value(), kDefaultResourceName); + // Send initial response. + LoadStatsResponse response; + for (const std::string& cluster_name : cluster_names_) { + response.add_clusters(cluster_name); + } + response.mutable_load_reporting_interval()->set_seconds( + client_load_reporting_interval_seconds_); + stream->Write(response); + IncreaseResponseCount(); + // Wait for report. + request.Clear(); + while (stream->Read(&request)) { + gpr_log(GPR_INFO, "LRS[%p]: received client load report message: %s", + this, request.DebugString().c_str()); + std::vector stats; + for (const auto& cluster_stats : request.cluster_stats()) { + stats.emplace_back(cluster_stats); } + grpc_core::MutexLock lock(&load_report_mu_); + result_queue_.emplace_back(std::move(stats)); + if (load_report_cond_ != nullptr) load_report_cond_->Signal(); } // Wait until notified done. grpc_core::MutexLock lock(&lrs_mu_); - lrs_cv_.WaitUntil(&lrs_mu_, [this] { return lrs_done; }); + lrs_cv_.WaitUntil(&lrs_mu_, [this] { return lrs_done_; }); } gpr_log(GPR_INFO, "LRS[%p]: StreamLoadStats done", this); return Status::OK; } + // Must be called before the LRS call is started. + void set_cluster_names(const std::set& cluster_names) { + cluster_names_ = cluster_names; + } + void Start() { - lrs_done = false; - load_report_ready_ = false; - client_stats_.reset(); + lrs_done_ = false; + result_queue_.clear(); } void Shutdown() { @@ -997,12 +1023,18 @@ class LrsServiceImpl : public LrsService, gpr_log(GPR_INFO, "LRS[%p]: shut down", this); } - ClientStats* WaitForLoadReport() { + std::vector WaitForLoadReport() { grpc_core::MutexLock lock(&load_report_mu_); - load_report_cond_.WaitUntil(&load_report_mu_, - [this] { return load_report_ready_; }); - load_report_ready_ = false; - return client_stats_.get(); + grpc_core::CondVar cv; + if (result_queue_.empty()) { + load_report_cond_ = &cv; + load_report_cond_->WaitUntil(&load_report_mu_, + [this] { return !result_queue_.empty(); }); + load_report_cond_ = nullptr; + } + std::vector result = std::move(result_queue_.front()); + result_queue_.pop_front(); + return result; } void NotifyDoneWithLrsCall() { @@ -1010,26 +1042,24 @@ class LrsServiceImpl : public LrsService, NotifyDoneWithLrsCallLocked(); } + private: void NotifyDoneWithLrsCallLocked() { - if (!lrs_done) { - lrs_done = true; + if (!lrs_done_) { + lrs_done_ = true; lrs_cv_.Broadcast(); } } - private: const int client_load_reporting_interval_seconds_; + std::set cluster_names_; grpc_core::CondVar lrs_cv_; - // Protect lrs_done. - grpc_core::Mutex lrs_mu_; - bool lrs_done = false; + grpc_core::Mutex lrs_mu_; // Protects lrs_done_. + bool lrs_done_ = false; - grpc_core::CondVar load_report_cond_; - // Protect the members below. - grpc_core::Mutex load_report_mu_; - std::unique_ptr client_stats_; - bool load_report_ready_ = false; + grpc_core::Mutex load_report_mu_; // Protects the members below. + grpc_core::CondVar* load_report_cond_ = nullptr; + std::deque> result_queue_; }; class TestType { @@ -1056,8 +1086,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam { protected: XdsEnd2endTest(size_t num_backends, size_t num_balancers, int client_load_reporting_interval_seconds = 100) - : server_host_("localhost"), - num_backends_(num_backends), + : num_backends_(num_backends), num_balancers_(num_balancers), client_load_reporting_interval_seconds_( client_load_reporting_interval_seconds) {} @@ -1085,7 +1114,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam { // Start the backends. for (size_t i = 0; i < num_backends_; ++i) { backends_.emplace_back(new BackendServerThread); - backends_.back()->Start(server_host_); + backends_.back()->Start(); } // Start the load balancers. for (size_t i = 0; i < num_balancers_; ++i) { @@ -1093,7 +1122,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam { new BalancerServerThread(GetParam().enable_load_reporting() ? client_load_reporting_interval_seconds_ : 0)); - balancers_.back()->Start(server_host_); + balancers_.back()->Start(); } ResetStub(); } @@ -1104,10 +1133,10 @@ class XdsEnd2endTest : public ::testing::TestWithParam { } void StartAllBackends() { - for (auto& backend : backends_) backend->Start(server_host_); + for (auto& backend : backends_) backend->Start(); } - void StartBackend(size_t index) { backends_[index]->Start(server_host_); } + void StartBackend(size_t index) { backends_[index]->Start(); } void ShutdownAllBackends() { for (auto& backend : backends_) backend->Shutdown(); @@ -1360,7 +1389,7 @@ class XdsEnd2endTest : public ::testing::TestWithParam { ServerThread() : port_(g_port_saver->GetPort()) {} virtual ~ServerThread(){}; - void Start(const grpc::string& server_host) { + void Start() { gpr_log(GPR_INFO, "starting %s server on port %d", Type(), port_); GPR_ASSERT(!running_); running_ = true; @@ -1370,19 +1399,18 @@ class XdsEnd2endTest : public ::testing::TestWithParam { // by ServerThread::Serve from firing before the wait below is hit. grpc_core::MutexLock lock(&mu); grpc_core::CondVar cond; - thread_.reset(new std::thread( - std::bind(&ServerThread::Serve, this, server_host, &mu, &cond))); + thread_.reset( + new std::thread(std::bind(&ServerThread::Serve, this, &mu, &cond))); cond.Wait(&mu); gpr_log(GPR_INFO, "%s server startup complete", Type()); } - void Serve(const grpc::string& server_host, grpc_core::Mutex* mu, - grpc_core::CondVar* cond) { + void Serve(grpc_core::Mutex* mu, grpc_core::CondVar* cond) { // We need to acquire the lock here in order to prevent the notify_one // below from firing before its corresponding wait is executed. grpc_core::MutexLock lock(mu); std::ostringstream server_address; - server_address << server_host << ":" << port_; + server_address << "localhost:" << port_; ServerBuilder builder; std::shared_ptr creds(new SecureServerCredentials( grpc_fake_transport_security_server_credentials_create())); @@ -1441,8 +1469,8 @@ class XdsEnd2endTest : public ::testing::TestWithParam { : ads_service_(new AdsServiceImpl(client_load_reporting_interval > 0)), lrs_service_(new LrsServiceImpl(client_load_reporting_interval)) {} - std::shared_ptr ads_service() { return ads_service_; } - std::shared_ptr lrs_service() { return lrs_service_; } + AdsServiceImpl* ads_service() { return ads_service_.get(); } + LrsServiceImpl* lrs_service() { return lrs_service_.get(); } private: void RegisterAllServices(ServerBuilder* builder) override { @@ -1466,7 +1494,6 @@ class XdsEnd2endTest : public ::testing::TestWithParam { std::shared_ptr lrs_service_; }; - const grpc::string server_host_; const size_t num_backends_; const size_t num_balancers_; const int client_load_reporting_interval_seconds_; @@ -1720,6 +1747,187 @@ TEST_P(XdsResolverOnlyTest, ClusterRemoved) { AdsServiceImpl::ACKED); } +// Tests that we restart all xDS requests when we reestablish the ADS call. +TEST_P(XdsResolverOnlyTest, RestartsRequestsUponReconnection) { + balancers_[0]->ads_service()->SetLdsToUseDynamicRds(); + const char* kNewClusterName = "new_cluster_name"; + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts(0, 2)}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); + // We need to wait for all backends to come online. + WaitForAllBackends(0, 2); + // Now shut down and restart the balancer. When the client + // reconnects, it should automatically restart the requests for all + // resource types. + balancers_[0]->Shutdown(); + balancers_[0]->Start(); + // Make sure things are still working. + CheckRpcSendOk(100); + // Populate new EDS resource. + AdsServiceImpl::EdsResourceArgs args2({ + {"locality0", GetBackendPorts(2, 4)}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args2, kNewClusterName), + kNewClusterName); + // Populate new CDS resource. + Cluster new_cluster = balancers_[0]->ads_service()->default_cluster(); + new_cluster.set_name(kNewClusterName); + balancers_[0]->ads_service()->SetCdsResource(new_cluster, kNewClusterName); + // Change RDS resource to point to new cluster. + RouteConfiguration new_route_config = + balancers_[0]->ads_service()->default_route_config(); + new_route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_route() + ->set_cluster(kNewClusterName); + balancers_[0]->ads_service()->SetRdsResource(new_route_config, + kDefaultResourceName); + // Wait for all new backends to be used. + std::tuple counts = WaitForAllBackends(2, 4); + // Make sure no RPCs failed in the transition. + EXPECT_EQ(0, std::get<1>(counts)); +} + +class XdsResolverLoadReportingOnlyTest : public XdsEnd2endTest { + public: + XdsResolverLoadReportingOnlyTest() : XdsEnd2endTest(4, 1, 3) {} +}; + +// Tests load reporting when switching over from one cluster to another. +TEST_P(XdsResolverLoadReportingOnlyTest, ChangeClusters) { + const char* kNewClusterName = "new_cluster_name"; + balancers_[0]->lrs_service()->set_cluster_names( + {kDefaultResourceName, kNewClusterName}); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // cluster kDefaultResourceName -> locality0 -> backends 0 and 1 + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts(0, 2)}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); + // cluster kNewClusterName -> locality1 -> backends 2 and 3 + AdsServiceImpl::EdsResourceArgs args2({ + {"locality1", GetBackendPorts(2, 4)}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args2, kNewClusterName), + kNewClusterName); + // CDS resource for kNewClusterName. + Cluster new_cluster = balancers_[0]->ads_service()->default_cluster(); + new_cluster.set_name(kNewClusterName); + balancers_[0]->ads_service()->SetCdsResource(new_cluster, kNewClusterName); + // Wait for all backends to come online. + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(0, 2); + // The load report received at the balancer should be correct. + std::vector load_report = + balancers_[0]->lrs_service()->WaitForLoadReport(); + EXPECT_THAT( + load_report, + ::testing::ElementsAre(::testing::AllOf( + ::testing::Property(&ClientStats::cluster_name, kDefaultResourceName), + ::testing::Property( + &ClientStats::locality_stats, + ::testing::ElementsAre(::testing::Pair( + "locality0", + ::testing::AllOf( + ::testing::Field(&ClientStats::LocalityStats:: + total_successful_requests, + num_ok), + ::testing::Field(&ClientStats::LocalityStats:: + total_requests_in_progress, + 0UL), + ::testing::Field( + &ClientStats::LocalityStats::total_error_requests, + num_failure), + ::testing::Field( + &ClientStats::LocalityStats::total_issued_requests, + num_failure + num_ok))))), + ::testing::Property(&ClientStats::total_dropped_requests, + num_drops)))); + // Change RDS resource to point to new cluster. + RouteConfiguration new_route_config = + balancers_[0]->ads_service()->default_route_config(); + new_route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_route() + ->set_cluster(kNewClusterName); + Listener listener = + balancers_[0]->ads_service()->BuildListener(new_route_config); + balancers_[0]->ads_service()->SetLdsResource(listener, kDefaultResourceName); + // Wait for all new backends to be used. + std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(2, 4); + // The load report received at the balancer should be correct. + load_report = balancers_[0]->lrs_service()->WaitForLoadReport(); + EXPECT_THAT( + load_report, + ::testing::ElementsAre( + ::testing::AllOf( + ::testing::Property(&ClientStats::cluster_name, + kDefaultResourceName), + ::testing::Property( + &ClientStats::locality_stats, + ::testing::ElementsAre(::testing::Pair( + "locality0", + ::testing::AllOf( + ::testing::Field(&ClientStats::LocalityStats:: + total_successful_requests, + ::testing::Lt(num_ok)), + ::testing::Field(&ClientStats::LocalityStats:: + total_requests_in_progress, + 0UL), + ::testing::Field( + &ClientStats::LocalityStats::total_error_requests, + ::testing::Le(num_failure)), + ::testing::Field( + &ClientStats::LocalityStats:: + total_issued_requests, + ::testing::Le(num_failure + num_ok)))))), + ::testing::Property(&ClientStats::total_dropped_requests, + num_drops)), + ::testing::AllOf( + ::testing::Property(&ClientStats::cluster_name, kNewClusterName), + ::testing::Property( + &ClientStats::locality_stats, + ::testing::ElementsAre(::testing::Pair( + "locality1", + ::testing::AllOf( + ::testing::Field(&ClientStats::LocalityStats:: + total_successful_requests, + ::testing::Le(num_ok)), + ::testing::Field(&ClientStats::LocalityStats:: + total_requests_in_progress, + 0UL), + ::testing::Field( + &ClientStats::LocalityStats::total_error_requests, + ::testing::Le(num_failure)), + ::testing::Field( + &ClientStats::LocalityStats:: + total_issued_requests, + ::testing::Le(num_failure + num_ok)))))), + ::testing::Property(&ClientStats::total_dropped_requests, + num_drops)))); + int total_ok = 0; + int total_failure = 0; + for (const ClientStats& client_stats : load_report) { + total_ok += client_stats.total_successful_requests(); + total_failure += client_stats.total_error_requests(); + } + EXPECT_EQ(total_ok, num_ok); + EXPECT_EQ(total_failure, num_failure); + // The LRS service got a single request, and sent a single response. + EXPECT_EQ(1U, balancers_[0]->lrs_service()->request_count()); + EXPECT_EQ(1U, balancers_[0]->lrs_service()->response_count()); +} + using SecureNamingTest = BasicTest; // Tests that secure naming check passes if target name is expected. @@ -2205,8 +2413,6 @@ TEST_P(CdsTest, Timeout) { using EdsTest = BasicTest; -// TODO(roth): Add tests showing that RPCs fail when EDS data is invalid. - TEST_P(EdsTest, Timeout) { ResetStub(0, 0, "", 500); balancers_[0]->ads_service()->SetResourceIgnore(kEdsTypeUrl); @@ -2215,6 +2421,34 @@ TEST_P(EdsTest, Timeout) { CheckRpcSendFailure(); } +// Tests that EDS client should send a NACK if the EDS update contains +// no localities but does not say to drop all calls. +TEST_P(EdsTest, NacksNoLocalitiesWithoutDropAll) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + AdsServiceImpl::EdsResourceArgs args; + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); + CheckRpcSendFailure(); + EXPECT_EQ(balancers_[0]->ads_service()->eds_response_state(), + AdsServiceImpl::NACKED); +} + +// Tests that EDS client should send a NACK if the EDS update contains +// sparse priorities. +TEST_P(EdsTest, NacksSparsePriorityList) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts(), kDefaultLocalityWeight, 1}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); + CheckRpcSendFailure(); + EXPECT_EQ(balancers_[0]->ads_service()->eds_response_state(), + AdsServiceImpl::NACKED); +} + using LocalityMapTest = BasicTest; // Tests that the localities in a locality map are picked according to their @@ -2259,6 +2493,33 @@ TEST_P(LocalityMapTest, WeightedRoundRobin) { ::testing::Le(kLocalityWeightRate1 * (1 + kErrorTolerance)))); } +// Tests that we correctly handle a locality containing no endpoints. +TEST_P(LocalityMapTest, LocalityContainingNoEndpoints) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 5000; + // EDS response contains 2 localities, one with no endpoints. + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + {"locality1", {}}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); + // Wait for both backends to be ready. + WaitForAllBackends(); + // Send kNumRpcs RPCs. + CheckRpcSendOk(kNumRpcs); + // All traffic should go to the reachable locality. + EXPECT_EQ(backends_[0]->backend_service()->request_count(), + kNumRpcs / backends_.size()); + EXPECT_EQ(backends_[1]->backend_service()->request_count(), + kNumRpcs / backends_.size()); + EXPECT_EQ(backends_[2]->backend_service()->request_count(), + kNumRpcs / backends_.size()); + EXPECT_EQ(backends_[3]->backend_service()->request_count(), + kNumRpcs / backends_.size()); +} + // Tests that the locality map can work properly even when it contains a large // number of localities. TEST_P(LocalityMapTest, StressTest) { @@ -2298,7 +2559,7 @@ TEST_P(LocalityMapTest, StressTest) { TEST_P(LocalityMapTest, UpdateMap) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 1000; + const size_t kNumRpcs = 3000; // The locality weight for the first 3 localities. const std::vector kLocalityWeights0 = {2, 3, 4}; const double kTotalLocalityWeight0 = @@ -2340,6 +2601,8 @@ TEST_P(LocalityMapTest, UpdateMap) { } const double kErrorTolerance = 0.2; for (size_t i = 0; i < 3; ++i) { + gpr_log(GPR_INFO, "Locality %" PRIuPTR " rate %f", i, + locality_picked_rates[i]); EXPECT_THAT( locality_picked_rates[i], ::testing::AllOf( @@ -2357,7 +2620,7 @@ TEST_P(LocalityMapTest, UpdateMap) { EXPECT_EQ(0U, backends_[3]->backend_service()->request_count()); // Wait until the locality update has been processed, as signaled by backend 3 // receiving a request. - WaitForBackend(3); + WaitForAllBackends(3, 4); gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); // Send kNumRpcs RPCs. CheckRpcSendOk(kNumRpcs); @@ -2373,6 +2636,8 @@ TEST_P(LocalityMapTest, UpdateMap) { kNumRpcs); } for (size_t i = 1; i < 4; ++i) { + gpr_log(GPR_INFO, "Locality %" PRIuPTR " rate %f", i, + locality_picked_rates[i]); EXPECT_THAT( locality_picked_rates[i], ::testing::AllOf( @@ -2432,6 +2697,24 @@ TEST_P(FailoverTest, ChooseHighestPriority) { } } +// Does not choose priority with no endpoints. +TEST_P(FailoverTest, DoesNotUsePriorityWithNoEndpoints) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, + {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, + {"locality3", {}, kDefaultLocalityWeight, 0}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); + WaitForBackend(0, false); + for (size_t i = 1; i < 3; ++i) { + EXPECT_EQ(0U, backends_[i]->backend_service()->request_count()); + } +} + // If the higher priority localities are not reachable, failover to the highest // priority among the rest. TEST_P(FailoverTest, Failover) { @@ -2717,7 +3000,7 @@ TEST_P(DropTest, DropPerTenThousand) { TEST_P(DropTest, Update) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 1000; + const size_t kNumRpcs = 3000; const uint32_t kDropPerMillionForLb = 100000; const uint32_t kDropPerMillionForThrottle = 200000; const double kDropRateForLb = kDropPerMillionForLb / 1000000.0; @@ -2750,6 +3033,7 @@ TEST_P(DropTest, Update) { gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); // The drop rate should be roughly equal to the expectation. double seen_drop_rate = static_cast(num_drops) / kNumRpcs; + gpr_log(GPR_INFO, "First batch drop rate %f", seen_drop_rate); const double kErrorTolerance = 0.3; EXPECT_THAT( seen_drop_rate, @@ -2798,6 +3082,7 @@ TEST_P(DropTest, Update) { gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); // The new drop rate should be roughly equal to the expectation. seen_drop_rate = static_cast(num_drops) / kNumRpcs; + gpr_log(GPR_INFO, "Second batch drop rate %f", seen_drop_rate); EXPECT_THAT( seen_drop_rate, ::testing::AllOf( @@ -2813,9 +3098,7 @@ TEST_P(DropTest, DropAll) { const uint32_t kDropPerMillionForLb = 100000; const uint32_t kDropPerMillionForThrottle = 1000000; // The ADS response contains two drop categories. - AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); + AdsServiceImpl::EdsResourceArgs args; args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, {kThrottleDropType, kDropPerMillionForThrottle}}; balancers_[0]->ads_service()->SetEdsResource( @@ -2824,8 +3107,8 @@ TEST_P(DropTest, DropAll) { for (size_t i = 0; i < kNumRpcs; ++i) { EchoResponse response; const Status status = SendRpc(&response); - EXPECT_TRUE(!status.ok() && status.error_message() == - "Call dropped by load balancing policy"); + EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); + EXPECT_EQ(status.error_message(), "Call dropped by load balancing policy"); } } @@ -3031,7 +3314,7 @@ TEST_P(FallbackTest, FallbackModeIsExitedWhenBalancerSaysToDropAllCalls) { } // Tests that fallback mode is exited if the child policy becomes ready. -TEST_P(FallbackTest, FallbackModeIsExitedAfterChildRready) { +TEST_P(FallbackTest, FallbackModeIsExitedAfterChildReady) { // Return an unreachable balancer and one fallback backend. SetNextResolution({backends_[0]->port()}); SetNextResolutionForLbChannel({g_port_saver->GetPort()}); @@ -3301,14 +3584,50 @@ TEST_P(ClientLoadReportingTest, Vanilla) { EXPECT_EQ(1U, balancers_[0]->lrs_service()->request_count()); EXPECT_EQ(1U, balancers_[0]->lrs_service()->response_count()); // The load report received at the balancer should be correct. - ClientStats* client_stats = balancers_[0]->lrs_service()->WaitForLoadReport(); + std::vector load_report = + balancers_[0]->lrs_service()->WaitForLoadReport(); + ASSERT_EQ(load_report.size(), 1UL); + ClientStats& client_stats = load_report.front(); EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + num_ok, - client_stats->total_successful_requests()); - EXPECT_EQ(0U, client_stats->total_requests_in_progress()); + client_stats.total_successful_requests()); + EXPECT_EQ(0U, client_stats.total_requests_in_progress()); EXPECT_EQ(kNumRpcsPerAddress * num_backends_ + num_ok, - client_stats->total_issued_requests()); - EXPECT_EQ(0U, client_stats->total_error_requests()); - EXPECT_EQ(0U, client_stats->total_dropped_requests()); + client_stats.total_issued_requests()); + EXPECT_EQ(0U, client_stats.total_error_requests()); + EXPECT_EQ(0U, client_stats.total_dropped_requests()); +} + +// Tests that we don't include stats for clusters that are not requested +// by the LRS server. +TEST_P(ClientLoadReportingTest, HonorsClustersRequestedByLrsServer) { + balancers_[0]->lrs_service()->set_cluster_names({"bogus"}); + SetNextResolution({}); + SetNextResolutionForLbChannel({balancers_[0]->port()}); + const size_t kNumRpcsPerAddress = 100; + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + AdsServiceImpl::BuildEdsResource(args), kDefaultResourceName); + // Wait until all backends are ready. + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + // Each backend should have gotten 100 requests. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, + backends_[i]->backend_service()->request_count()); + } + // The LRS service got a single request, and sent a single response. + EXPECT_EQ(1U, balancers_[0]->lrs_service()->request_count()); + EXPECT_EQ(1U, balancers_[0]->lrs_service()->response_count()); + // The load report received at the balancer should be correct. + std::vector load_report = + balancers_[0]->lrs_service()->WaitForLoadReport(); + ASSERT_EQ(load_report.size(), 0UL); } // Tests that if the balancer restarts, the client load report contains the @@ -3331,12 +3650,15 @@ TEST_P(ClientLoadReportingTest, BalancerRestart) { std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(/* start_index */ 0, /* stop_index */ kNumBackendsFirstPass); - ClientStats* client_stats = balancers_[0]->lrs_service()->WaitForLoadReport(); + std::vector load_report = + balancers_[0]->lrs_service()->WaitForLoadReport(); + ASSERT_EQ(load_report.size(), 1UL); + ClientStats client_stats = std::move(load_report.front()); EXPECT_EQ(static_cast(num_ok), - client_stats->total_successful_requests()); - EXPECT_EQ(0U, client_stats->total_requests_in_progress()); - EXPECT_EQ(0U, client_stats->total_error_requests()); - EXPECT_EQ(0U, client_stats->total_dropped_requests()); + client_stats.total_successful_requests()); + EXPECT_EQ(0U, client_stats.total_requests_in_progress()); + EXPECT_EQ(0U, client_stats.total_error_requests()); + EXPECT_EQ(0U, client_stats.total_dropped_requests()); // Shut down the balancer. balancers_[0]->Shutdown(); // We should continue using the last EDS response we received from the @@ -3353,7 +3675,7 @@ TEST_P(ClientLoadReportingTest, BalancerRestart) { int num_started = std::get<0>(WaitForAllBackends( /* start_index */ 0, /* stop_index */ kNumBackendsFirstPass)); // Now restart the balancer, this time pointing to the new backends. - balancers_[0]->Start(server_host_); + balancers_[0]->Start(); args = AdsServiceImpl::EdsResourceArgs({ {"locality0", GetBackendPorts(kNumBackendsFirstPass)}, }); @@ -3368,11 +3690,13 @@ TEST_P(ClientLoadReportingTest, BalancerRestart) { CheckRpcSendOk(kNumBackendsSecondPass); num_started += kNumBackendsSecondPass; // Check client stats. - client_stats = balancers_[0]->lrs_service()->WaitForLoadReport(); - EXPECT_EQ(num_started, client_stats->total_successful_requests()); - EXPECT_EQ(0U, client_stats->total_requests_in_progress()); - EXPECT_EQ(0U, client_stats->total_error_requests()); - EXPECT_EQ(0U, client_stats->total_dropped_requests()); + load_report = balancers_[0]->lrs_service()->WaitForLoadReport(); + ASSERT_EQ(load_report.size(), 1UL); + client_stats = std::move(load_report.front()); + EXPECT_EQ(num_started, client_stats.total_successful_requests()); + EXPECT_EQ(0U, client_stats.total_requests_in_progress()); + EXPECT_EQ(0U, client_stats.total_error_requests()); + EXPECT_EQ(0U, client_stats.total_dropped_requests()); } class ClientLoadReportingWithDropTest : public XdsEnd2endTest { @@ -3426,15 +3750,18 @@ TEST_P(ClientLoadReportingWithDropTest, Vanilla) { ::testing::Ge(KDropRateForLbAndThrottle * (1 - kErrorTolerance)), ::testing::Le(KDropRateForLbAndThrottle * (1 + kErrorTolerance)))); // Check client stats. - ClientStats* client_stats = balancers_[0]->lrs_service()->WaitForLoadReport(); - EXPECT_EQ(num_drops, client_stats->total_dropped_requests()); + std::vector load_report = + balancers_[0]->lrs_service()->WaitForLoadReport(); + ASSERT_EQ(load_report.size(), 1UL); + ClientStats& client_stats = load_report.front(); + EXPECT_EQ(num_drops, client_stats.total_dropped_requests()); const size_t total_rpc = num_warmup + kNumRpcs; EXPECT_THAT( - client_stats->dropped_requests(kLbDropType), + client_stats.dropped_requests(kLbDropType), ::testing::AllOf( ::testing::Ge(total_rpc * kDropRateForLb * (1 - kErrorTolerance)), ::testing::Le(total_rpc * kDropRateForLb * (1 + kErrorTolerance)))); - EXPECT_THAT(client_stats->dropped_requests(kThrottleDropType), + EXPECT_THAT(client_stats.dropped_requests(kThrottleDropType), ::testing::AllOf( ::testing::Ge(total_rpc * (1 - kDropRateForLb) * kDropRateForThrottle * (1 - kErrorTolerance)), @@ -3491,6 +3818,11 @@ INSTANTIATE_TEST_SUITE_P(XdsTest, XdsResolverOnlyTest, TestType(true, true)), &TestTypeName); +// XdsResolverLoadReprtingOnlyTest depends on XdsResolver and load reporting. +INSTANTIATE_TEST_SUITE_P(XdsTest, XdsResolverLoadReportingOnlyTest, + ::testing::Values(TestType(true, true)), + &TestTypeName); + INSTANTIATE_TEST_SUITE_P(XdsTest, LocalityMapTest, ::testing::Values(TestType(false, true), TestType(false, false), diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index e4674fb0d4b..7e8d371fc3c 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -90,6 +90,7 @@ grpc_cc_test( grpc_cc_test( name = "bm_arena", + size = "large", srcs = ["bm_arena.cc"], tags = [ "no_mac", @@ -249,7 +250,6 @@ grpc_cc_test( grpc_cc_test( name = "bm_metadata", srcs = ["bm_metadata.cc"], - flaky = True, # TODO(b/149998903) tags = [ "no_mac", "no_windows", @@ -283,6 +283,7 @@ grpc_cc_test( grpc_cc_test( name = "bm_opencensus_plugin", srcs = ["bm_opencensus_plugin.cc"], + flaky = True, # TODO(b/151696309) language = "C++", deps = [ ":helpers_secure", diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc index b03901b92ee..f323ae0c012 100644 --- a/test/cpp/naming/resolver_component_test.cc +++ b/test/cpp/naming/resolver_component_test.cc @@ -39,6 +39,7 @@ #include "test/cpp/util/test_config.h" #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/resolver.h" #include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" @@ -463,19 +464,20 @@ class CheckingResultHandler : public ResultHandler { void CheckResult(const grpc_core::Resolver::Result& result) override { ArgsStruct* args = args_struct(); - gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR, - result.addresses.size(), args->expected_addrs.size()); - GPR_ASSERT(result.addresses.size() == args->expected_addrs.size()); std::vector found_lb_addrs; - for (size_t i = 0; i < result.addresses.size(); i++) { - const grpc_core::ServerAddress& addr = result.addresses[i]; - char* str; - grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); - gpr_log(GPR_INFO, "%s", str); - found_lb_addrs.emplace_back( - GrpcLBAddress(std::string(str), addr.IsBalancer())); - gpr_free(str); + AddActualAddresses(result.addresses, /*is_balancer=*/false, + &found_lb_addrs); + const grpc_core::ServerAddressList* balancer_addresses = + grpc_core::FindGrpclbBalancerAddressesInChannelArgs(*result.args); + if (balancer_addresses != nullptr) { + AddActualAddresses(*balancer_addresses, /*is_balancer=*/true, + &found_lb_addrs); } + gpr_log(GPR_INFO, + "found %" PRIdPTR " backend addresses and %" PRIdPTR + " balancer addresses", + result.addresses.size(), + balancer_addresses == nullptr ? 0L : balancer_addresses->size()); if (args->expected_addrs.size() != found_lb_addrs.size()) { gpr_log(GPR_DEBUG, "found lb addrs size is: %" PRIdPTR @@ -495,6 +497,20 @@ class CheckingResultHandler : public ResultHandler { CheckLBPolicyResultLocked(result.args, args); } } + + private: + static void AddActualAddresses(const grpc_core::ServerAddressList& addresses, + bool is_balancer, + std::vector* out) { + for (size_t i = 0; i < addresses.size(); i++) { + const grpc_core::ServerAddress& addr = addresses[i]; + char* str; + grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */); + gpr_log(GPR_INFO, "%s", str); + out->emplace_back(GrpcLBAddress(std::string(str), is_balancer)); + gpr_free(str); + } + } }; int g_fake_non_responsive_dns_server_port = -1; diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py index 53d9364a35b..274c9a1b345 100755 --- a/test/cpp/naming/resolver_component_tests_runner.py +++ b/test/cpp/naming/resolver_component_tests_runner.py @@ -331,7 +331,7 @@ current_test_subprocess = subprocess.Popen([ args.test_bin_path, '--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.', '--expected_addrs', '1.2.3.4:443,False', - '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true}]}', + '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThirteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFourteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFifteen","service":"SimpleService"}],"waitForReady":true}]}', '--expected_service_config_error', '', '--expected_lb_policy', '', '--enable_srv_queries', 'True', diff --git a/test/cpp/naming/resolver_test_record_groups.yaml b/test/cpp/naming/resolver_test_record_groups.yaml index a1d932ae2b7..c44c39faecc 100644 --- a/test/cpp/naming/resolver_test_record_groups.yaml +++ b/test/cpp/naming/resolver_test_record_groups.yaml @@ -205,7 +205,7 @@ resolver_component_tests: - {TTL: '2100', data: '2607:f8b0:400a:801::1002', type: AAAA} - expected_addrs: - {address: '1.2.3.4:443', is_balancer: false} - expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true}]}' + expected_chosen_service_config: '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThirteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFourteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFifteen","service":"SimpleService"}],"waitForReady":true}]}' expected_service_config_error: null expected_lb_policy: null enable_srv_queries: true @@ -216,7 +216,7 @@ resolver_component_tests: ipv4-config-causing-fallback-to-tcp: - {TTL: '2100', data: 1.2.3.4, type: A} _grpc_config.ipv4-config-causing-fallback-to-tcp: - - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true}]}}]', + - {TTL: '2100', data: 'grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwo","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThree","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFour","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFive","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSix","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooSeven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEight","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooNine","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooEleven","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooTwelve","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooThirteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFourteen","service":"SimpleService"}],"waitForReady":true},{"name":[{"method":"FooFifteen","service":"SimpleService"}],"waitForReady":true}]}}]', type: TXT} # Tests for which we don't enable SRV queries - expected_addrs: diff --git a/tools/buildgen/extract_metadata_from_bazel_xml.py b/tools/buildgen/extract_metadata_from_bazel_xml.py index b50a1feb854..720ce54f6c1 100755 --- a/tools/buildgen/extract_metadata_from_bazel_xml.py +++ b/tools/buildgen/extract_metadata_from_bazel_xml.py @@ -564,14 +564,6 @@ def _generate_build_extra_metadata_for_tests(tests, bazel_rules): % (test_name, long_name)) test_metadata[test_name]['_RENAME'] = long_name - # TODO(jtattermusch): in bazel, add "_test" suffix to the test names - # test does not have "_test" suffix: fling - # test does not have "_test" suffix: fling_stream - # test does not have "_test" suffix: client_ssl - # test does not have "_test" suffix: handshake_server_with_readahead_handshaker - # test does not have "_test" suffix: handshake_verify_peer_options - # test does not have "_test" suffix: server_ssl - return test_metadata diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index bc774227fff..2983441176d 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -44,7 +44,7 @@ class GuardValidator(object): self.ifndef_re = re.compile(r'#ifndef ([A-Z][A-Z_1-9]*)') self.define_re = re.compile(r'#define ([A-Z][A-Z_1-9]*)') self.endif_c_re = re.compile( - r'#endif /\* ([A-Z][A-Z_1-9]*) (?:\\ *\n *)?\*/') + r'#endif /\* (?: *\\\n *)?([A-Z][A-Z_1-9]*) (?:\\\n *)?\*/$') self.endif_cpp_re = re.compile(r'#endif // ([A-Z][A-Z_1-9]*)') self.failed = False @@ -122,7 +122,7 @@ class GuardValidator(object): # Is there a properly commented #endif? endif_re = self.endif_cpp_re if cpp_header else self.endif_c_re flines = fcontents.rstrip().splitlines() - match = endif_re.search('\n'.join(flines[-2:])) + match = endif_re.search('\n'.join(flines[-3:])) if not match: # No endif. Check if we have the last line as just '#endif' and if so # replace it with a properly commented one. diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5c5d1c9fac5..edbe236dc17 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1097,6 +1097,8 @@ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filte src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h \ +src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ +src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 20087420e4e..5c03ac61231 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -894,6 +894,8 @@ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filte src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h \ +src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc \ +src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ diff --git a/tools/internal_ci/linux/grpc_xds.cfg b/tools/internal_ci/linux/grpc_xds.cfg index 888be05cde5..107404a30e9 100644 --- a/tools/internal_ci/linux/grpc_xds.cfg +++ b/tools/internal_ci/linux/grpc_xds.cfg @@ -15,9 +15,15 @@ # Config file for the internal CI (in protobuf text format) # Location of the continuous shell script in repository. -build_file: "grpc/tools/internal_ci/linux/grpc_bazel.sh" +build_file: "grpc/tools/internal_ci/linux/grpc_xds.sh" timeout_mins: 90 env_vars { key: "BAZEL_SCRIPT" value: "tools/internal_ci/linux/grpc_xds_bazel_test_in_docker.sh" } +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} diff --git a/tools/internal_ci/linux/grpc_xds.sh b/tools/internal_ci/linux/grpc_xds.sh new file mode 100755 index 00000000000..6de6588024c --- /dev/null +++ b/tools/internal_ci/linux/grpc_xds.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# 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. + +set -ex + +# change to grpc repo root +cd $(dirname $0)/../../.. + +source tools/internal_ci/helper_scripts/prepare_build_linux_rc + +export DOCKERFILE_DIR=tools/dockerfile/test/bazel +export DOCKER_RUN_SCRIPT=$BAZEL_SCRIPT +export OUTPUT_DIR=reports +exec tools/run_tests/dockerize/build_and_run_docker.sh diff --git a/tools/internal_ci/linux/grpc_xds_bazel_python_test_in_docker.sh b/tools/internal_ci/linux/grpc_xds_bazel_python_test_in_docker.sh new file mode 100755 index 00000000000..0dbea2f59ee --- /dev/null +++ b/tools/internal_ci/linux/grpc_xds_bazel_python_test_in_docker.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# Copyright 2020 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. + +set -ex -o igncr || set -ex + +mkdir -p /var/local/git +git clone /var/local/jenkins/grpc /var/local/git/grpc +(cd /var/local/jenkins/grpc/ && git submodule foreach 'cd /var/local/git/grpc \ +&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \ +${name}') +cd /var/local/git/grpc + +VIRTUAL_ENV=$(mktemp -d) +virtualenv "$VIRTUAL_ENV" +PYTHON="$VIRTUAL_ENV"/bin/python +"$PYTHON" -m pip install --upgrade grpcio-tools google-api-python-client google-auth-httplib2 oauth2client + +# Prepare generated Python code. +TOOLS_DIR=tools/run_tests +PROTO_SOURCE_DIR=src/proto/grpc/testing +PROTO_DEST_DIR="$TOOLS_DIR"/"$PROTO_SOURCE_DIR" +mkdir -p "$PROTO_DEST_DIR" +touch "$TOOLS_DIR"/src/__init__.py +touch "$TOOLS_DIR"/src/proto/__init__.py +touch "$TOOLS_DIR"/src/proto/grpc/__init__.py +touch "$TOOLS_DIR"/src/proto/grpc/testing/__init__.py + +"$PYTHON" -m grpc_tools.protoc \ + --proto_path=. \ + --python_out="$TOOLS_DIR" \ + --grpc_python_out="$TOOLS_DIR" \ + "$PROTO_SOURCE_DIR"/test.proto \ + "$PROTO_SOURCE_DIR"/messages.proto \ + "$PROTO_SOURCE_DIR"/empty.proto + +bazel build //src/python/grpcio_tests/tests_py3_only/interop:xds_interop_client + +GRPC_VERBOSITY=debug GRPC_TRACE=xds_client,xds_resolver,cds_lb,xds_lb "$PYTHON" \ + tools/run_tests/run_xds_tests.py \ + --test_case=all \ + --project_id=grpc-testing \ + --gcp_suffix=$(date '+%s') \ + --verbose \ + --client_cmd='bazel run //src/python/grpcio_tests/tests_py3_only/interop:xds_interop_client -- --server=xds-experimental:///{server_uri} --stats_port={stats_port} --qps={qps} --verbose' diff --git a/tools/internal_ci/linux/grpc_xds_python.cfg b/tools/internal_ci/linux/grpc_xds_python.cfg new file mode 100644 index 00000000000..922b1aa88a1 --- /dev/null +++ b/tools/internal_ci/linux/grpc_xds_python.cfg @@ -0,0 +1,29 @@ +# Copyright 2020 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_xds.sh" +timeout_mins: 90 +env_vars { + key: "BAZEL_SCRIPT" + value: "tools/internal_ci/linux/grpc_xds_bazel_python_test_in_docker.sh" +} +action { + define_artifacts { + regex: "**/*sponge_log.*" + regex: "github/grpc/reports/**" + } +} diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 92768508834..96e2b33c614 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -104,6 +104,7 @@ LANG_RELEASE_MATRIX = { ('v1.24.0', ReleaseInfo()), ('v1.25.0', ReleaseInfo()), ('v1.26.0', ReleaseInfo()), + ('v1.27.3', ReleaseInfo()), ]), 'go': OrderedDict([ @@ -268,6 +269,7 @@ LANG_RELEASE_MATRIX = { ('v1.24.0', ReleaseInfo(runtimes=['python'])), ('v1.25.0', ReleaseInfo(runtimes=['python'])), ('v1.26.0', ReleaseInfo(runtimes=['python'])), + ('v1.27.3', ReleaseInfo(runtimes=['python'])), ]), 'node': OrderedDict([ @@ -325,6 +327,7 @@ LANG_RELEASE_MATRIX = { # If you are not encountering the error in above issue # go ahead and upload the docker image for new releases. ('v1.26.0', ReleaseInfo()), + ('v1.27.3', ReleaseInfo()), ]), 'php': OrderedDict([ @@ -355,6 +358,7 @@ LANG_RELEASE_MATRIX = { ('v1.24.0', ReleaseInfo()), ('v1.25.0', ReleaseInfo()), ('v1.26.0', ReleaseInfo()), + ('v1.27.3', ReleaseInfo()), ]), 'csharp': OrderedDict([ @@ -390,5 +394,6 @@ LANG_RELEASE_MATRIX = { ('v1.24.0', ReleaseInfo()), ('v1.25.0', ReleaseInfo()), ('v1.26.0', ReleaseInfo()), + ('v1.27.3', ReleaseInfo()), ]), } diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index 91a991d534f..b413ab4c2c7 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -325,6 +325,19 @@ def checkout_grpc_stack(lang, release): '%s: %s' % (str(output), commit_log), do_newline=True) + # git submodule update + jobset.message('START', + 'git submodule update --init at %s from %s' % + (release, stack_base), + do_newline=True) + subprocess.check_call(['git', 'submodule', 'update', '--init'], + cwd=stack_base, + stderr=subprocess.STDOUT) + jobset.message('SUCCESS', + 'git submodule update --init', + '%s: %s' % (str(output), commit_log), + do_newline=True) + # Write git log to commit_log so it can be packaged with the docker image. with open(os.path.join(stack_base, 'commit_log'), 'w') as f: f.write(commit_log) diff --git a/tools/package_hosting/home.xsl b/tools/package_hosting/home.xsl index 3f79303b1b7..8550953174c 100644 --- a/tools/package_hosting/home.xsl +++ b/tools/package_hosting/home.xsl @@ -46,6 +46,7 @@
  • Dart: pub package grpc
  • Go: go get google.golang.org/grpc
  • Java: Use JARs from gRPC Maven Central Repository
  • +
  • Kotlin: Use JARs from gRPC Maven Central Repository
  • Node: npm install grpc
  • Objective-C: Add gRPC-ProtoRPC dependency to podspec
  • PHP: pecl install grpc
  • diff --git a/tools/remote_build/mac.bazelrc b/tools/remote_build/mac.bazelrc index fb8833a9618..cc201565f71 100644 --- a/tools/remote_build/mac.bazelrc +++ b/tools/remote_build/mac.bazelrc @@ -4,9 +4,6 @@ # but try to use RBE build cache and upload results # to ResultStore -# don't use port server -build --define GRPC_PORT_ISOLATED_RUNTIME=1 - startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 # remote cache is needed not only for build speedup, diff --git a/tools/remote_build/windows.bazelrc b/tools/remote_build/windows.bazelrc index f4508e00d0f..4f6979478f9 100644 --- a/tools/remote_build/windows.bazelrc +++ b/tools/remote_build/windows.bazelrc @@ -38,9 +38,6 @@ build --define GRPC_PORT_ISOLATED_RUNTIME=1 build --test_tag_filters=-no_windows build --build_tag_filters=-no_windows -# required for the tests to pass on Windows RBE -build --incompatible_windows_native_test_wrapper - # without verbose gRPC logs the test outputs are not very useful test --test_env=GRPC_VERBOSITY=debug diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index df3a9edc202..16ec891f747 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -731,7 +731,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "client_ssl", + "name": "client_ssl_test", "platforms": [ "linux", "mac", @@ -1251,7 +1251,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "fling", + "name": "fling_stream_test", "platforms": [ "linux", "mac", @@ -1273,7 +1273,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "fling_stream", + "name": "fling_test", "platforms": [ "linux", "mac", @@ -1485,7 +1485,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "handshake_server_with_readahead_handshaker", + "name": "handshake_server_with_readahead_handshaker_test", "platforms": [ "linux", "mac", @@ -1507,7 +1507,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "handshake_verify_peer_options", + "name": "handshake_verify_peer_options_test", "platforms": [ "linux", "mac", @@ -2423,30 +2423,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": false, - "language": "c", - "name": "sequential_connectivity_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -2485,7 +2461,7 @@ "flaky": false, "gtest": false, "language": "c", - "name": "server_ssl", + "name": "server_ssl_test", "platforms": [ "linux", "mac", @@ -3849,6 +3825,26 @@ ], "uses_polling": true }, + { + "args": [], + "benchmark": true, + "ci_platforms": [ + "linux", + "posix" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c++", + "name": "bm_metadata", + "platforms": [ + "linux", + "posix" + ], + "uses_polling": false + }, { "args": [], "benchmark": true, @@ -4081,30 +4077,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "channelz_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -4199,28 +4171,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "client_lb_end2end_test", - "platforms": [ - "linux", - "mac", - "posix" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, @@ -4413,30 +4363,6 @@ ], "uses_polling": true }, - { - "args": [], - "benchmark": false, - "ci_platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "gtest": true, - "language": "c++", - "name": "end2end_test", - "platforms": [ - "linux", - "mac", - "posix", - "windows" - ], - "uses_polling": true - }, { "args": [], "benchmark": false, diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 0923454f560..4bf2186b26b 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -70,8 +70,7 @@ do tools/run_tests/performance/build_performance_node.sh ;; "python") - # python workers are only run with python2.7 and building with multiple python versions is costly - python tools/run_tests/run_tests.py -l "$language" -c "$CONFIG" --compiler python2.7 --build_only -j 8 + $bazel build -c opt //src/python/grpcio_tests/tests/qps:qps_worker ;; "python_asyncio") $bazel build -c opt //src/python/grpcio_tests/tests_aio/benchmark:worker diff --git a/tools/run_tests/performance/run_worker_python.sh b/tools/run_tests/performance/run_worker_python.sh index 5281fce360a..674ae2797e6 100755 --- a/tools/run_tests/performance/run_worker_python.sh +++ b/tools/run_tests/performance/run_worker_python.sh @@ -17,4 +17,4 @@ set -ex cd "$(dirname "$0")/../../.." -PYTHONPATH=src/python/grpcio_tests:src/python/gens py27_native/bin/python src/python/grpcio_tests/tests/qps/qps_worker.py "$@" +bazel-bin/src/python/grpcio_tests/tests/qps/qps_worker "$@" diff --git a/tools/run_tests/python_utils/report_utils.py b/tools/run_tests/python_utils/report_utils.py index 43aaf50af04..666edbf63d6 100644 --- a/tools/run_tests/python_utils/report_utils.py +++ b/tools/run_tests/python_utils/report_utils.py @@ -31,9 +31,9 @@ def _filter_msg(msg, output_format): if output_format in ['XML', 'HTML']: # keep whitespaces but remove formfeed and vertical tab characters # that make XML report unparsable. - filtered_msg = filter( - lambda x: x in string.printable and x != '\f' and x != '\v', - msg.decode('UTF-8', 'ignore')) + filtered_msg = ''.join( + filter(lambda x: x in string.printable and x != '\f' and x != '\v', + msg.decode('UTF-8', 'ignore'))) if output_format == 'HTML': filtered_msg = filtered_msg.replace('"', '"') return filtered_msg diff --git a/tools/run_tests/python_utils/upload_rbe_results.py b/tools/run_tests/python_utils/upload_rbe_results.py index 36fb5f2537b..8aedd72afbf 100755 --- a/tools/run_tests/python_utils/upload_rbe_results.py +++ b/tools/run_tests/python_utils/upload_rbe_results.py @@ -37,6 +37,7 @@ _RESULTS_SCHEMA = [ ('build_id', 'INTEGER', 'Build ID of Kokoro job'), ('build_url', 'STRING', 'URL of Kokoro build'), ('test_target', 'STRING', 'Bazel target path'), + ('test_class_name', 'STRING', 'Name of test class'), ('test_case', 'STRING', 'Name of test case'), ('result', 'STRING', 'Test or build result'), ('timestamp', 'TIMESTAMP', 'Timestamp of test run'), @@ -134,15 +135,42 @@ def _get_resultstore_data(api_key, invocation_id): if __name__ == "__main__": # Arguments are necessary if running in a non-Kokoro environment. - argp = argparse.ArgumentParser(description='Upload RBE results.') - argp.add_argument('--api_key', default='', type=str) - argp.add_argument('--invocation_id', default='', type=str) + argp = argparse.ArgumentParser( + description= + 'Fetches results for given RBE invocation and uploads them to BigQuery table.' + ) + argp.add_argument('--api_key', + default='', + type=str, + help='The API key to read from ResultStore API') + argp.add_argument('--invocation_id', + default='', + type=str, + help='UUID of bazel invocation to fetch.') + argp.add_argument('--bq_dump_file', + default=None, + type=str, + help='Dump JSON data to file just before uploading') + argp.add_argument('--resultstore_dump_file', + default=None, + type=str, + help='Dump JSON data as received from ResultStore API') + argp.add_argument('--skip_upload', + default=False, + action='store_const', + const=True, + help='Skip uploading to bigquery') args = argp.parse_args() api_key = args.api_key or _get_api_key() invocation_id = args.invocation_id or _get_invocation_id() resultstore_actions = _get_resultstore_data(api_key, invocation_id) + if args.resultstore_dump_file: + with open(args.resultstore_dump_file, 'w') as f: + json.dump(resultstore_actions, f, indent=4, sort_keys=True) + print('Dumped resultstore data to file %s' % args.resultstore_dump_file) + # google.devtools.resultstore.v2.Action schema: # https://github.com/googleapis/googleapis/blob/master/google/devtools/resultstore/v2/action.proto bq_rows = [] @@ -189,8 +217,9 @@ if __name__ == "__main__": elif 'tests' not in action['testAction']['testSuite']: continue else: - test_cases = action['testAction']['testSuite']['tests'][0][ - 'testSuite']['tests'] + test_cases = [] + for tests_item in action['testAction']['testSuite']['tests']: + test_cases += tests_item['testSuite']['tests'] for test_case in test_cases: if any(s in test_case['testCase'] for s in ['errors', 'failures']): result = 'FAILED' @@ -213,6 +242,8 @@ if __name__ == "__main__": % invocation_id, 'test_target': action['id']['targetId'], + 'test_class_name': + test_case['testCase'].get('className', ''), 'test_case': test_case['testCase']['caseName'], 'result': @@ -238,6 +269,8 @@ if __name__ == "__main__": % invocation_id, 'test_target': action['id']['targetId'], + 'test_class_name': + 'N/A', 'test_case': 'N/A', 'result': @@ -247,6 +280,14 @@ if __name__ == "__main__": } }) - # BigQuery sometimes fails with large uploads, so batch 1,000 rows at a time. - for i in range((len(bq_rows) / 1000) + 1): - _upload_results_to_bq(bq_rows[i * 1000:(i + 1) * 1000]) + if args.bq_dump_file: + with open(args.bq_dump_file, 'w') as f: + json.dump(bq_rows, f, indent=4, sort_keys=True) + print('Dumped BQ data to file %s' % args.bq_dump_file) + + if not args.skip_upload: + # BigQuery sometimes fails with large uploads, so batch 1,000 rows at a time. + for i in range((len(bq_rows) / 1000) + 1): + _upload_results_to_bq(bq_rows[i * 1000:(i + 1) * 1000]) + else: + print('Skipped upload to bigquery.') diff --git a/tools/run_tests/run_tests_matrix.py b/tools/run_tests/run_tests_matrix.py index 86f2f86037b..730bae8aef9 100755 --- a/tools/run_tests/run_tests_matrix.py +++ b/tools/run_tests/run_tests_matrix.py @@ -30,13 +30,9 @@ os.chdir(_ROOT) _DEFAULT_RUNTESTS_TIMEOUT = 1 * 60 * 60 -# Set the timeout high to allow enough time for sanitizers and pre-building -# clang docker. +# C/C++ tests can take long time _CPP_RUNTESTS_TIMEOUT = 4 * 60 * 60 -# C++ TSAN takes longer than other sanitizers -_CPP_TSAN_RUNTESTS_TIMEOUT = 8 * 60 * 60 - # Set timeout high for ObjC for Cocoapods to install pods _OBJC_RUNTESTS_TIMEOUT = 90 * 60 @@ -261,35 +257,6 @@ def _create_test_jobs(extra_args=[], inner_jobs=_DEFAULT_INNER_JOBS): inner_jobs=inner_jobs, timeout_seconds=_OBJC_RUNTESTS_TIMEOUT) - # sanitizers - test_jobs += _generate_jobs(languages=['c'], - configs=['msan', 'asan', 'tsan', 'ubsan'], - platforms=['linux'], - arch='x64', - compiler='clang7.0', - labels=['sanitizers', 'corelang'], - extra_args=extra_args, - inner_jobs=inner_jobs, - timeout_seconds=_CPP_RUNTESTS_TIMEOUT) - test_jobs += _generate_jobs(languages=['c++'], - configs=['asan'], - platforms=['linux'], - arch='x64', - compiler='clang7.0', - labels=['sanitizers', 'corelang'], - extra_args=extra_args, - inner_jobs=inner_jobs, - timeout_seconds=_CPP_RUNTESTS_TIMEOUT) - test_jobs += _generate_jobs(languages=['c++'], - configs=['tsan'], - platforms=['linux'], - arch='x64', - compiler='clang7.0', - labels=['sanitizers', 'corelang'], - extra_args=extra_args, - inner_jobs=inner_jobs, - timeout_seconds=_CPP_TSAN_RUNTESTS_TIMEOUT) - return test_jobs diff --git a/tools/run_tests/run_xds_tests.py b/tools/run_tests/run_xds_tests.py index b34b7e06a36..3f9fab3c806 100755 --- a/tools/run_tests/run_xds_tests.py +++ b/tools/run_tests/run_xds_tests.py @@ -29,6 +29,9 @@ import time from oauth2client.client import GoogleCredentials +import python_utils.jobset as jobset +import python_utils.report_utils as report_utils + from src.proto.grpc.testing import messages_pb2 from src.proto.grpc.testing import test_pb2_grpc @@ -36,7 +39,29 @@ logger = logging.getLogger() console_handler = logging.StreamHandler() formatter = logging.Formatter(fmt='%(asctime)s: %(levelname)-8s %(message)s') console_handler.setFormatter(formatter) +logger.handlers = [] logger.addHandler(console_handler) +logger.setLevel(logging.WARNING) + +_TEST_CASES = [ + 'backends_restart', + 'change_backend_service', + 'new_instance_group_receives_traffic', + 'ping_pong', + 'remove_instance_group', + 'round_robin', + 'secondary_locality_gets_no_requests_on_partial_primary_failure', + 'secondary_locality_gets_requests_on_primary_failure', +] + + +def parse_test_cases(arg): + if arg == 'all': + return _TEST_CASES + test_cases = arg.split(',') + if all([test_case in _TEST_CASES for test_case in test_cases]): + return test_cases + raise Exception('Failed to parse test cases %s' % arg) def parse_port_range(port_arg): @@ -58,17 +83,9 @@ argp.add_argument( argp.add_argument( '--test_case', default='ping_pong', - choices=[ - 'all', - 'backends_restart', - 'change_backend_service', - 'new_instance_group_receives_traffic', - 'ping_pong', - 'remove_instance_group', - 'round_robin', - 'secondary_locality_gets_no_requests_on_partial_primary_failure', - 'secondary_locality_gets_requests_on_primary_failure', - ]) + type=parse_test_cases, + help='Comma-separated list of test cases to run, or \'all\' to run every ' + 'test. Available tests: %s' % ' '.join(_TEST_CASES)) argp.add_argument( '--client_cmd', default=None, @@ -82,7 +99,7 @@ argp.add_argument('--secondary_zone', argp.add_argument('--qps', default=10, type=int, help='Client QPS') argp.add_argument( '--wait_for_backend_sec', - default=600, + default=1200, type=int, help='Time limit for waiting for created backend services to report ' 'healthy when launching or updated GCP resources') @@ -128,6 +145,13 @@ argp.add_argument('--source_image', argp.add_argument('--machine_type', default='e2-standard-2', help='Machine type for VMs created during the test') +argp.add_argument( + '--instance_group_size', + default=2, + type=int, + help='Number of VMs to create per instance group. Certain test cases (e.g., ' + 'round_robin) may not give meaningful results if this is set to a value ' + 'less than 2.') argp.add_argument( '--tolerate_gcp_errors', default=False, @@ -147,15 +171,21 @@ if args.verbose: _DEFAULT_SERVICE_PORT = 80 _WAIT_FOR_BACKEND_SEC = args.wait_for_backend_sec -_WAIT_FOR_OPERATION_SEC = 120 -_INSTANCE_GROUP_SIZE = 2 +_WAIT_FOR_OPERATION_SEC = 300 +_INSTANCE_GROUP_SIZE = args.instance_group_size _NUM_TEST_RPCS = 10 * args.qps -_WAIT_FOR_STATS_SEC = 120 +_WAIT_FOR_STATS_SEC = 180 _WAIT_FOR_URL_MAP_PATCH_SEC = 300 _BOOTSTRAP_TEMPLATE = """ {{ "node": {{ - "id": "{node_id}" + "id": "{node_id}", + "metadata": {{ + "TRAFFICDIRECTOR_NETWORK_NAME": "%s" + }}, + "locality": {{ + "zone": "%s" + }} }}, "xds_servers": [{{ "server_uri": "%s", @@ -166,7 +196,13 @@ _BOOTSTRAP_TEMPLATE = """ }} ] }}] -}}""" % args.xds_server +}}""" % (args.network.split('/')[-1], args.zone, args.xds_server) +_TESTS_USING_SECONDARY_IG = [ + 'secondary_locality_gets_no_requests_on_partial_primary_failure', + 'secondary_locality_gets_requests_on_primary_failure' +] +_USE_SECONDARY_IG = any( + [t in args.test_case for t in _TESTS_USING_SECONDARY_IG]) _PATH_MATCHER_NAME = 'path-matcher' _BASE_TEMPLATE_NAME = 'test-template' _BASE_INSTANCE_GROUP_NAME = 'test-ig' @@ -177,6 +213,10 @@ _BASE_URL_MAP_NAME = 'test-map' _BASE_SERVICE_HOST = 'grpc-test' _BASE_TARGET_PROXY_NAME = 'test-target-proxy' _BASE_FORWARDING_RULE_NAME = 'test-forwarding-rule' +_TEST_LOG_BASE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), + '../../reports') +_SPONGE_LOG_NAME = 'sponge_log.log' +_SPONGE_XML_NAME = 'sponge_log.xml' def get_client_stats(num_rpcs, timeout_sec): @@ -712,7 +752,10 @@ def patch_backend_instances(gcp, wait_for_global_operation(gcp, result['name']) -def resize_instance_group(gcp, instance_group, new_size, timeout_sec=120): +def resize_instance_group(gcp, + instance_group, + new_size, + timeout_sec=_WAIT_FOR_OPERATION_SEC): result = gcp.compute.instanceGroupManagers().resize( project=gcp.project, zone=instance_group.zone, @@ -896,8 +939,6 @@ if args.compute_discovery_document: else: compute = googleapiclient.discovery.build('compute', 'v1') -client_process = None - try: gcp = GcpState(compute, args.project_id) health_check_name = _BASE_HEALTH_CHECK_NAME + args.gcp_suffix @@ -911,7 +952,8 @@ try: template_name = _BASE_TARGET_PROXY_NAME + args.gcp_suffix instance_group_name = _BASE_INSTANCE_GROUP_NAME + args.gcp_suffix same_zone_instance_group_name = _BASE_INSTANCE_GROUP_NAME + '-same-zone' + args.gcp_suffix - secondary_zone_instance_group_name = _BASE_INSTANCE_GROUP_NAME + '-secondary-zone' + args.gcp_suffix + if _USE_SECONDARY_IG: + secondary_zone_instance_group_name = _BASE_INSTANCE_GROUP_NAME + '-secondary-zone' + args.gcp_suffix try: create_health_check(gcp, health_check_name) create_health_check_firewall_rule(gcp, firewall_name) @@ -951,9 +993,10 @@ try: patch_backend_instances(gcp, backend_service, [instance_group]) same_zone_instance_group = add_instance_group( gcp, args.zone, same_zone_instance_group_name, _INSTANCE_GROUP_SIZE) - secondary_zone_instance_group = add_instance_group( - gcp, args.secondary_zone, secondary_zone_instance_group_name, - _INSTANCE_GROUP_SIZE) + if _USE_SECONDARY_IG: + secondary_zone_instance_group = add_instance_group( + gcp, args.secondary_zone, secondary_zone_instance_group_name, + _INSTANCE_GROUP_SIZE) except googleapiclient.errors.HttpError as http_error: if args.tolerate_gcp_errors: logger.warning( @@ -994,14 +1037,16 @@ try: same_zone_instance_group_name, result['selfLink'], args.zone) gcp.instance_groups.append(same_zone_instance_group) - result = compute.instanceGroups().get( - project=args.project_id, - zone=args.secondary_zone, - instanceGroup=secondary_zone_instance_group_name).execute() - secondary_zone_instance_group = InstanceGroup( - secondary_zone_instance_group_name, result['selfLink'], - args.secondary_zone) - gcp.instance_groups.append(secondary_zone_instance_group) + if _USE_SECONDARY_IG: + result = compute.instanceGroups().get( + project=args.project_id, + zone=args.secondary_zone, + instanceGroup=secondary_zone_instance_group_name + ).execute() + secondary_zone_instance_group = InstanceGroup( + secondary_zone_instance_group_name, result['selfLink'], + args.secondary_zone) + gcp.instance_groups.append(secondary_zone_instance_group) if not gcp.health_check: result = compute.healthChecks().get( project=args.project_id, @@ -1025,56 +1070,85 @@ try: server_uri = service_host_name else: server_uri = service_host_name + ':' + str(gcp.service_port) - cmd = args.client_cmd.format(server_uri=server_uri, - stats_port=args.stats_port, - qps=args.qps) - client_process = start_xds_client(cmd) - - if args.test_case == 'all': - test_backends_restart(gcp, backend_service, instance_group) - test_change_backend_service(gcp, backend_service, instance_group, - alternate_backend_service, - same_zone_instance_group) - test_new_instance_group_receives_traffic(gcp, backend_service, - instance_group, - same_zone_instance_group) - test_ping_pong(gcp, backend_service, instance_group) - test_remove_instance_group(gcp, backend_service, instance_group, - same_zone_instance_group) - test_round_robin(gcp, backend_service, instance_group) - test_secondary_locality_gets_no_requests_on_partial_primary_failure( - gcp, backend_service, instance_group, secondary_zone_instance_group) - test_secondary_locality_gets_requests_on_primary_failure( - gcp, backend_service, instance_group, secondary_zone_instance_group) - elif args.test_case == 'backends_restart': - test_backends_restart(gcp, backend_service, instance_group) - elif args.test_case == 'change_backend_service': - test_change_backend_service(gcp, backend_service, instance_group, - alternate_backend_service, - same_zone_instance_group) - elif args.test_case == 'new_instance_group_receives_traffic': - test_new_instance_group_receives_traffic(gcp, backend_service, - instance_group, - same_zone_instance_group) - elif args.test_case == 'ping_pong': - test_ping_pong(gcp, backend_service, instance_group) - elif args.test_case == 'remove_instance_group': - test_remove_instance_group(gcp, backend_service, instance_group, - same_zone_instance_group) - elif args.test_case == 'round_robin': - test_round_robin(gcp, backend_service, instance_group) - elif args.test_case == 'secondary_locality_gets_no_requests_on_partial_primary_failure': - test_secondary_locality_gets_no_requests_on_partial_primary_failure( - gcp, backend_service, instance_group, secondary_zone_instance_group) - elif args.test_case == 'secondary_locality_gets_requests_on_primary_failure': - test_secondary_locality_gets_requests_on_primary_failure( - gcp, backend_service, instance_group, secondary_zone_instance_group) - else: - logger.error('Unknown test case: %s', args.test_case) + with tempfile.NamedTemporaryFile(delete=False) as bootstrap_file: + bootstrap_file.write( + _BOOTSTRAP_TEMPLATE.format( + node_id=socket.gethostname()).encode('utf-8')) + bootstrap_path = bootstrap_file.name + client_env = dict(os.environ, GRPC_XDS_BOOTSTRAP=bootstrap_path) + client_cmd = shlex.split( + args.client_cmd.format(server_uri=server_uri, + stats_port=args.stats_port, + qps=args.qps)) + + test_results = {} + failed_tests = [] + for test_case in args.test_case: + result = jobset.JobResult() + log_dir = os.path.join(_TEST_LOG_BASE_DIR, test_case) + if not os.path.exists(log_dir): + os.makedirs(log_dir) + test_log_file = open(os.path.join(log_dir, _SPONGE_LOG_NAME), 'w+') + client_process = None + try: + client_process = subprocess.Popen(client_cmd, + env=client_env, + stderr=subprocess.STDOUT, + stdout=test_log_file) + if test_case == 'backends_restart': + test_backends_restart(gcp, backend_service, instance_group) + elif test_case == 'change_backend_service': + test_change_backend_service(gcp, backend_service, + instance_group, + alternate_backend_service, + same_zone_instance_group) + elif test_case == 'new_instance_group_receives_traffic': + test_new_instance_group_receives_traffic( + gcp, backend_service, instance_group, + same_zone_instance_group) + elif test_case == 'ping_pong': + test_ping_pong(gcp, backend_service, instance_group) + elif test_case == 'remove_instance_group': + test_remove_instance_group(gcp, backend_service, instance_group, + same_zone_instance_group) + elif test_case == 'round_robin': + test_round_robin(gcp, backend_service, instance_group) + elif test_case == 'secondary_locality_gets_no_requests_on_partial_primary_failure': + test_secondary_locality_gets_no_requests_on_partial_primary_failure( + gcp, backend_service, instance_group, + secondary_zone_instance_group) + elif test_case == 'secondary_locality_gets_requests_on_primary_failure': + test_secondary_locality_gets_requests_on_primary_failure( + gcp, backend_service, instance_group, + secondary_zone_instance_group) + else: + logger.error('Unknown test case: %s', test_case) + sys.exit(1) + result.state = 'PASSED' + result.returncode = 0 + except Exception as e: + logger.error('Test case %s failed: %s', test_case, e) + failed_tests.append(test_case) + result.state = 'FAILED' + result.message = str(e) + finally: + if client_process: + client_process.terminate() + # Workaround for Python 3, as report_utils will invoke decode() on + # result.message, which has a default value of ''. + result.message = result.message.encode('UTF-8') + test_results[test_case] = [result] + if not os.path.exists(_TEST_LOG_BASE_DIR): + os.makedirs(_TEST_LOG_BASE_DIR) + report_utils.render_junit_xml_report(test_results, + os.path.join(_TEST_LOG_BASE_DIR, + _SPONGE_XML_NAME), + suite_name='xds_tests', + multi_target=True) + if failed_tests: + logger.error('Test case(s) %s failed', failed_tests) sys.exit(1) finally: - if client_process: - client_process.terminate() if not args.keep_gcp_resources: logger.info('Cleaning up GCP resources. This may take some time.') clean_up(gcp)