diff --git a/BUILD b/BUILD index 81e1ad65cd1..f83a6bdc989 100644 --- a/BUILD +++ b/BUILD @@ -296,6 +296,7 @@ GRPC_PUBLIC_HDRS = [ "include/grpc/grpc_posix.h", "include/grpc/grpc_security.h", "include/grpc/grpc_security_constants.h", + "include/grpc/passive_listener.h", "include/grpc/slice.h", "include/grpc/slice_buffer.h", "include/grpc/status.h", @@ -457,6 +458,7 @@ GRPCXX_PUBLIC_HDRS = [ "include/grpcpp/impl/service_type.h", "include/grpcpp/impl/status.h", "include/grpcpp/impl/sync.h", + "include/grpcpp/passive_listener.h", "include/grpcpp/resource_quota.h", "include/grpcpp/security/audit_logging.h", "include/grpcpp/security/tls_crl_provider.h", @@ -581,6 +583,7 @@ grpc_cc_library( defines = ["GRPC_NO_XDS"], external_deps = [ "absl/base:core_headers", + "absl/log:log", ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, @@ -652,6 +655,7 @@ grpc_cc_library( }), external_deps = [ "absl/base:core_headers", + "absl/log:log", ], language = "c++", public_hdrs = GRPC_PUBLIC_HDRS, @@ -785,9 +789,9 @@ grpc_cc_library( "absl/base:core_headers", "absl/base:log_severity", "absl/functional:any_invocable", - "absl/log", "absl/log:check", "absl/log:globals", + "absl/log:log", "absl/memory", "absl/random", "absl/status", @@ -883,7 +887,7 @@ grpc_cc_library( grpc_cc_library( name = "grpc_public_hdrs", - hdrs = GRPC_PUBLIC_HDRS, + hdrs = GRPC_PUBLIC_HDRS + GRPC_PUBLIC_EVENT_ENGINE_HDRS, external_deps = [ "absl/status:statusor", "absl/strings", @@ -904,6 +908,7 @@ grpc_cc_library( hdrs = GRPCXX_PUBLIC_HDRS, external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:cord", "absl/synchronization", "protobuf_headers", @@ -934,6 +939,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:cord", ], language = "c++", @@ -1003,6 +1009,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -1062,6 +1069,7 @@ grpc_cc_library( ], external_deps = [ "absl/container:flat_hash_set", + "absl/log:log", "absl/strings", "absl/types:optional", "absl/types:span", @@ -1134,6 +1142,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/memory", "absl/meta:type_traits", "absl/status", @@ -1247,6 +1256,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/synchronization", ], @@ -1379,6 +1389,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -1438,6 +1449,7 @@ grpc_cc_library( external_deps = [ "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", ], language = "c++", deps = [ @@ -1489,6 +1501,9 @@ grpc_cc_library( hdrs = [ "//src/core:lib/surface/api_trace.h", ], + external_deps = [ + "absl/log:log", + ], language = "c++", deps = [ "gpr", @@ -1643,6 +1658,7 @@ grpc_cc_library( "absl/container:flat_hash_set", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -1806,6 +1822,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", @@ -1895,6 +1912,7 @@ grpc_cc_library( "absl/container:flat_hash_set", "absl/hash", "absl/log:check", + "absl/log:log", "absl/random", "absl/status", "absl/status:statusor", @@ -1924,9 +1942,7 @@ grpc_cc_library( "promise", "ref_counted_ptr", "stats", - "//src/core:1999", "//src/core:activity", - "//src/core:arena", "//src/core:arena_promise", "//src/core:cancel_callback", "//src/core:channel_args", @@ -1940,6 +1956,7 @@ grpc_cc_library( "//src/core:error", "//src/core:error_utils", "//src/core:experiments", + "//src/core:interception_chain", "//src/core:iomgr_fwd", "//src/core:map", "//src/core:metadata_batch", @@ -2013,6 +2030,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/status", "absl/status:statusor", @@ -2059,6 +2077,7 @@ grpc_cc_library( "//src/core:arena_promise", "//src/core:atomic_utils", "//src/core:bitset", + "//src/core:call_destination", "//src/core:call_filters", "//src/core:call_final_info", "//src/core:call_finalization", @@ -2287,6 +2306,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2394,6 +2414,7 @@ grpc_cc_library( "//src/core:tsi/alts/handshaker/transport_security_common_api.h", ], external_deps = [ + "absl/log:log", "@com_google_protobuf//upb:base", "@com_google_protobuf//upb:mem", ], @@ -2452,6 +2473,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2508,6 +2530,7 @@ grpc_cc_library( "//src/core:grpc_backend_metric_provider", "//src/core:grpc_crl_provider", "//src/core:grpc_service_config", + "//src/core:grpc_transport_chttp2_server", "//src/core:grpc_transport_inproc", "//src/core:json", "//src/core:json_reader", @@ -2535,6 +2558,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2566,6 +2590,7 @@ grpc_cc_library( "grpc_security_base", "grpc_service_config_impl", "grpc_trace", + "grpc_transport_chttp2", "grpc_unsecure", "grpcpp_backend_metric_recorder", "grpcpp_call_metric_recorder", @@ -2587,6 +2612,7 @@ grpc_cc_library( "//src/core:grpc_backend_metric_provider", "//src/core:grpc_insecure_credentials", "//src/core:grpc_service_config", + "//src/core:grpc_transport_chttp2_server", "//src/core:grpc_transport_inproc", "//src/core:ref_counted", "//src/core:resource_quota", @@ -2689,6 +2715,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/strings", ], language = "c++", @@ -2965,6 +2992,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", ], language = "c++", visibility = ["@grpc:client_channel"], @@ -2985,7 +3013,10 @@ grpc_cc_library( name = "grpc_trace", srcs = ["//src/core:lib/debug/trace.cc"], hdrs = ["//src/core:lib/debug/trace.h"], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", visibility = ["@grpc:trace"], deps = [ @@ -3130,6 +3161,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -3166,6 +3198,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -3212,6 +3245,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:str_format", ], visibility = [ @@ -3243,6 +3277,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3277,6 +3312,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", ], @@ -3305,6 +3341,9 @@ grpc_cc_library( hdrs = [ "//src/core:lib/iomgr/internal_errqueue.h", ], + external_deps = [ + "absl/log:log", + ], tags = ["nofixdeps"], visibility = ["@grpc:iomgr_internal_errqueue"], deps = [ @@ -3323,6 +3362,7 @@ grpc_cc_library( "//src/core:lib/iomgr/buffer_list.h", ], external_deps = [ + "absl/log:log", "absl/strings", "absl/strings:str_format", "absl/types:optional", @@ -3369,6 +3409,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3536,6 +3577,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3569,6 +3611,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "@com_google_protobuf//upb:base", @@ -3611,6 +3654,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", ], @@ -3667,6 +3711,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3801,6 +3846,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3865,6 +3911,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:bind_front", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3919,6 +3966,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -3963,6 +4011,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", visibility = [ @@ -3990,6 +4039,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4050,7 +4100,10 @@ grpc_cc_library( "//src/core:lib/security/security_connector/load_system_roots_supported.h", "//src/core:lib/security/util/json_util.h", ], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", visibility = ["@grpc:public"], deps = [ @@ -4082,6 +4135,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "@com_google_protobuf//upb:base", "@com_google_protobuf//upb:mem", @@ -4142,6 +4196,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/types:span", "libcrypto", "libssl", @@ -4173,6 +4228,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/memory", "libssl", ], @@ -4204,6 +4260,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4252,6 +4309,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4337,6 +4395,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/memory", "absl/status", "absl/status:statusor", @@ -4503,6 +4562,7 @@ grpc_cc_library( external_deps = [ "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", ], @@ -4559,6 +4619,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/random:bit_gen_ref", "absl/status", "absl/strings", @@ -4601,6 +4662,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -4714,6 +4776,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/hash", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/random:bit_gen_ref", @@ -4840,6 +4903,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/types:span", ], diff --git a/CMakeLists.txt b/CMakeLists.txt index 787db67baa0..3499823786a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1052,6 +1052,7 @@ if(gRPC_BUILD_TESTS) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_cxx dualstack_socket_test) endif() + add_dependencies(buildtests_cxx dump_args_test) add_dependencies(buildtests_cxx duplicate_header_bad_client_test) add_dependencies(buildtests_cxx empty_batch_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_POSIX) @@ -2501,6 +2502,7 @@ add_library(grpc src/core/lib/transport/call_spine.cc src/core/lib/transport/connectivity_state.cc src/core/lib/transport/error_utils.cc + src/core/lib/transport/interception_chain.cc src/core/lib/transport/message.cc src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc @@ -2746,6 +2748,7 @@ foreach(_hdr include/grpc/impl/propagation_bits.h include/grpc/impl/slice_type.h include/grpc/load_reporting.h + include/grpc/passive_listener.h include/grpc/slice.h include/grpc/slice_buffer.h include/grpc/status.h @@ -3253,6 +3256,7 @@ add_library(grpc_unsecure src/core/lib/transport/call_spine.cc src/core/lib/transport/connectivity_state.cc src/core/lib/transport/error_utils.cc + src/core/lib/transport/interception_chain.cc src/core/lib/transport/message.cc src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc @@ -3446,6 +3450,7 @@ foreach(_hdr include/grpc/impl/propagation_bits.h include/grpc/impl/slice_type.h include/grpc/load_reporting.h + include/grpc/passive_listener.h include/grpc/slice.h include/grpc/slice_buffer.h include/grpc/status.h @@ -4314,6 +4319,7 @@ foreach(_hdr include/grpcpp/impl/service_type.h include/grpcpp/impl/status.h include/grpcpp/impl/sync.h + include/grpcpp/passive_listener.h include/grpcpp/resource_quota.h include/grpcpp/security/audit_logging.h include/grpcpp/security/auth_context.h @@ -5054,6 +5060,7 @@ foreach(_hdr include/grpcpp/impl/service_type.h include/grpcpp/impl/status.h include/grpcpp/impl/sync.h + include/grpcpp/passive_listener.h include/grpcpp/resource_quota.h include/grpcpp/security/audit_logging.h include/grpcpp/security/auth_context.h @@ -5361,6 +5368,7 @@ add_library(grpc_authorization_provider src/core/lib/transport/call_spine.cc src/core/lib/transport/connectivity_state.cc src/core/lib/transport/error_utils.cc + src/core/lib/transport/interception_chain.cc src/core/lib/transport/message.cc src/core/lib/transport/metadata.cc src/core/lib/transport/metadata_batch.cc @@ -5504,6 +5512,7 @@ foreach(_hdr include/grpc/impl/propagation_bits.h include/grpc/impl/slice_type.h include/grpc/load_reporting.h + include/grpc/passive_listener.h include/grpc/slice.h include/grpc/slice_buffer.h include/grpc/status.h @@ -12385,6 +12394,41 @@ endif() endif() if(gRPC_BUILD_TESTS) +add_executable(dump_args_test + src/core/lib/gprpp/dump_args.cc + test/core/gprpp/dump_args_test.cc +) +target_compile_features(dump_args_test PUBLIC cxx_std_14) +target_include_directories(dump_args_test + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} + ${_gRPC_RE2_INCLUDE_DIR} + ${_gRPC_SSL_INCLUDE_DIR} + ${_gRPC_UPB_GENERATED_DIR} + ${_gRPC_UPB_GRPC_GENERATED_DIR} + ${_gRPC_UPB_INCLUDE_DIR} + ${_gRPC_XXHASH_INCLUDE_DIR} + ${_gRPC_ZLIB_INCLUDE_DIR} + third_party/googletest/googletest/include + third_party/googletest/googletest + third_party/googletest/googlemock/include + third_party/googletest/googlemock + ${_gRPC_PROTO_GENS_DIR} +) + +target_link_libraries(dump_args_test + ${_gRPC_ALLTARGETS_LIBRARIES} + gtest + absl::any_invocable + absl::check +) + + +endif() +if(gRPC_BUILD_TESTS) + add_executable(duplicate_header_bad_client_test test/core/bad_client/bad_client.cc test/core/bad_client/tests/duplicate_header.cc @@ -26833,6 +26877,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/orca_load_report.grpc.pb.h + test/core/event_engine/event_engine_test_utils.cc test/core/test_util/cmdline.cc test/core/test_util/fuzzer_util.cc test/core/test_util/grpc_profiler.cc diff --git a/Makefile b/Makefile index a62edd7fca3..22625964566 100644 --- a/Makefile +++ b/Makefile @@ -1387,6 +1387,7 @@ LIBGRPC_SRC = \ src/core/lib/transport/call_spine.cc \ src/core/lib/transport/connectivity_state.cc \ src/core/lib/transport/error_utils.cc \ + src/core/lib/transport/interception_chain.cc \ src/core/lib/transport/message.cc \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ @@ -1775,6 +1776,7 @@ PUBLIC_HEADERS_C += \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ + include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ diff --git a/Package.swift b/Package.swift index 9a1f76a9dc2..c4405cf775f 100644 --- a/Package.swift +++ b/Package.swift @@ -93,6 +93,7 @@ let package = Package( "include/grpc/impl/propagation_bits.h", "include/grpc/impl/slice_type.h", "include/grpc/load_reporting.h", + "include/grpc/passive_listener.h", "include/grpc/slice.h", "include/grpc/slice_buffer.h", "include/grpc/status.h", @@ -1748,6 +1749,7 @@ let package = Package( "src/core/lib/transport/bdp_estimator.h", "src/core/lib/transport/call_arena_allocator.cc", "src/core/lib/transport/call_arena_allocator.h", + "src/core/lib/transport/call_destination.h", "src/core/lib/transport/call_filters.cc", "src/core/lib/transport/call_filters.h", "src/core/lib/transport/call_final_info.cc", @@ -1760,6 +1762,8 @@ let package = Package( "src/core/lib/transport/error_utils.cc", "src/core/lib/transport/error_utils.h", "src/core/lib/transport/http2_errors.h", + "src/core/lib/transport/interception_chain.cc", + "src/core/lib/transport/interception_chain.h", "src/core/lib/transport/message.cc", "src/core/lib/transport/message.h", "src/core/lib/transport/metadata.cc", diff --git a/bazel/experiments.bzl b/bazel/experiments.bzl index abd1166647f..0bd711b6641 100644 --- a/bazel/experiments.bzl +++ b/bazel/experiments.bzl @@ -34,9 +34,8 @@ EXPERIMENT_ENABLES = { "pending_queue_cap": "pending_queue_cap", "pick_first_new": "pick_first_new", "promise_based_client_call": "event_engine_client,event_engine_listener,promise_based_client_call", - "promise_based_server_call": "promise_based_server_call", - "chaotic_good": "chaotic_good,event_engine_client,event_engine_listener,promise_based_client_call,promise_based_server_call", - "promise_based_inproc_transport": "event_engine_client,event_engine_listener,promise_based_client_call,promise_based_inproc_transport,promise_based_server_call", + "chaotic_good": "chaotic_good,event_engine_client,event_engine_listener,promise_based_client_call", + "promise_based_inproc_transport": "event_engine_client,event_engine_listener,promise_based_client_call,promise_based_inproc_transport", "rstpit": "rstpit", "schedule_cancellation_over_write": "schedule_cancellation_over_write", "server_privacy": "server_privacy", @@ -59,17 +58,10 @@ EXPERIMENTS = { "dbg": { }, "off": { - "core_end2end_test": [ - "event_engine_client", - "promise_based_server_call", - ], "endpoint_test": [ "tcp_frame_size_tuning", "tcp_rcv_lowat", ], - "event_engine_client_test": [ - "event_engine_client", - ], "flow_control_test": [ "multiping", "peer_state_based_framing", @@ -77,9 +69,6 @@ EXPERIMENTS = { "tcp_frame_size_tuning", "tcp_rcv_lowat", ], - "logging_test": [ - "promise_based_server_call", - ], "resource_quota_test": [ "free_large_allocator", "unconstrained_max_quota_buffer_size", @@ -87,11 +76,15 @@ EXPERIMENTS = { }, "on": { "core_end2end_test": [ + "event_engine_client", "event_engine_listener", ], "cpp_lb_end2end_test": [ "pick_first_new", ], + "event_engine_client_test": [ + "event_engine_client", + ], "event_engine_listener_test": [ "event_engine_listener", ], @@ -107,9 +100,6 @@ EXPERIMENTS = { "dbg": { }, "off": { - "core_end2end_test": [ - "promise_based_server_call", - ], "endpoint_test": [ "tcp_frame_size_tuning", "tcp_rcv_lowat", @@ -121,9 +111,6 @@ EXPERIMENTS = { "tcp_frame_size_tuning", "tcp_rcv_lowat", ], - "logging_test": [ - "promise_based_server_call", - ], "resource_quota_test": [ "free_large_allocator", "unconstrained_max_quota_buffer_size", @@ -149,7 +136,6 @@ EXPERIMENTS = { "chaotic_good", "event_engine_client", "promise_based_client_call", - "promise_based_server_call", ], "endpoint_test": [ "tcp_frame_size_tuning", @@ -168,9 +154,6 @@ EXPERIMENTS = { "lame_client_test": [ "promise_based_client_call", ], - "logging_test": [ - "promise_based_server_call", - ], "resource_quota_test": [ "free_large_allocator", "unconstrained_max_quota_buffer_size", diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index dd845a6d959..b60ae5b5e2a 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -198,6 +198,7 @@ libs: - include/grpc/impl/propagation_bits.h - include/grpc/impl/slice_type.h - include/grpc/load_reporting.h + - include/grpc/passive_listener.h - include/grpc/slice.h - include/grpc/slice_buffer.h - include/grpc/status.h @@ -1109,6 +1110,7 @@ libs: - src/core/lib/transport/batch_builder.h - src/core/lib/transport/bdp_estimator.h - src/core/lib/transport/call_arena_allocator.h + - src/core/lib/transport/call_destination.h - src/core/lib/transport/call_filters.h - src/core/lib/transport/call_final_info.h - src/core/lib/transport/call_spine.h @@ -1116,6 +1118,7 @@ libs: - src/core/lib/transport/custom_metadata.h - src/core/lib/transport/error_utils.h - src/core/lib/transport/http2_errors.h + - src/core/lib/transport/interception_chain.h - src/core/lib/transport/message.h - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h @@ -1920,6 +1923,7 @@ libs: - src/core/lib/transport/call_spine.cc - src/core/lib/transport/connectivity_state.cc - src/core/lib/transport/error_utils.cc + - src/core/lib/transport/interception_chain.cc - src/core/lib/transport/message.cc - src/core/lib/transport/metadata.cc - src/core/lib/transport/metadata_batch.cc @@ -2182,6 +2186,7 @@ libs: - include/grpc/impl/propagation_bits.h - include/grpc/impl/slice_type.h - include/grpc/load_reporting.h + - include/grpc/passive_listener.h - include/grpc/slice.h - include/grpc/slice_buffer.h - include/grpc/status.h @@ -2607,6 +2612,7 @@ libs: - src/core/lib/transport/batch_builder.h - src/core/lib/transport/bdp_estimator.h - src/core/lib/transport/call_arena_allocator.h + - src/core/lib/transport/call_destination.h - src/core/lib/transport/call_filters.h - src/core/lib/transport/call_final_info.h - src/core/lib/transport/call_spine.h @@ -2614,6 +2620,7 @@ libs: - src/core/lib/transport/custom_metadata.h - src/core/lib/transport/error_utils.h - src/core/lib/transport/http2_errors.h + - src/core/lib/transport/interception_chain.h - src/core/lib/transport/message.h - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h @@ -3030,6 +3037,7 @@ libs: - src/core/lib/transport/call_spine.cc - src/core/lib/transport/connectivity_state.cc - src/core/lib/transport/error_utils.cc + - src/core/lib/transport/interception_chain.cc - src/core/lib/transport/message.cc - src/core/lib/transport/metadata.cc - src/core/lib/transport/metadata_batch.cc @@ -3786,6 +3794,7 @@ libs: - include/grpcpp/impl/service_type.h - include/grpcpp/impl/status.h - include/grpcpp/impl/sync.h + - include/grpcpp/passive_listener.h - include/grpcpp/resource_quota.h - include/grpcpp/security/audit_logging.h - include/grpcpp/security/auth_context.h @@ -4213,6 +4222,7 @@ libs: - include/grpcpp/impl/service_type.h - include/grpcpp/impl/status.h - include/grpcpp/impl/sync.h + - include/grpcpp/passive_listener.h - include/grpcpp/resource_quota.h - include/grpcpp/security/audit_logging.h - include/grpcpp/security/auth_context.h @@ -4361,6 +4371,7 @@ libs: - include/grpc/impl/propagation_bits.h - include/grpc/impl/slice_type.h - include/grpc/load_reporting.h + - include/grpc/passive_listener.h - include/grpc/slice.h - include/grpc/slice_buffer.h - include/grpc/status.h @@ -4681,6 +4692,7 @@ libs: - src/core/lib/surface/wait_for_cq_end_op.h - src/core/lib/transport/batch_builder.h - src/core/lib/transport/call_arena_allocator.h + - src/core/lib/transport/call_destination.h - src/core/lib/transport/call_filters.h - src/core/lib/transport/call_final_info.h - src/core/lib/transport/call_spine.h @@ -4688,6 +4700,7 @@ libs: - src/core/lib/transport/custom_metadata.h - src/core/lib/transport/error_utils.h - src/core/lib/transport/http2_errors.h + - src/core/lib/transport/interception_chain.h - src/core/lib/transport/message.h - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h @@ -4984,6 +4997,7 @@ libs: - src/core/lib/transport/call_spine.cc - src/core/lib/transport/connectivity_state.cc - src/core/lib/transport/error_utils.cc + - src/core/lib/transport/interception_chain.cc - src/core/lib/transport/message.cc - src/core/lib/transport/metadata.cc - src/core/lib/transport/metadata_batch.cc @@ -8656,6 +8670,20 @@ targets: - linux - posix - mac +- name: dump_args_test + gtest: true + build: test + language: c++ + headers: + - src/core/lib/gprpp/dump_args.h + src: + - src/core/lib/gprpp/dump_args.cc + - test/core/gprpp/dump_args_test.cc + deps: + - gtest + - absl/functional:any_invocable + - absl/log:check + uses_polling: false - name: duplicate_header_bad_client_test gtest: true build: test @@ -17784,6 +17812,7 @@ targets: build: test language: c++ headers: + - test/core/event_engine/event_engine_test_utils.h - test/core/test_util/cmdline.h - test/core/test_util/evaluate_args_test_util.h - test/core/test_util/fuzzer_util.h @@ -17799,6 +17828,7 @@ targets: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/simple_messages.proto - src/proto/grpc/testing/xds/v3/orca_load_report.proto + - test/core/event_engine/event_engine_test_utils.cc - test/core/test_util/cmdline.cc - test/core/test_util/fuzzer_util.cc - test/core/test_util/grpc_profiler.cc diff --git a/config.m4 b/config.m4 index d44618c5775..4b72ff9577e 100644 --- a/config.m4 +++ b/config.m4 @@ -762,6 +762,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/transport/call_spine.cc \ src/core/lib/transport/connectivity_state.cc \ src/core/lib/transport/error_utils.cc \ + src/core/lib/transport/interception_chain.cc \ src/core/lib/transport/message.cc \ src/core/lib/transport/metadata.cc \ src/core/lib/transport/metadata_batch.cc \ diff --git a/config.w32 b/config.w32 index 0d0a85c04d7..f71331b6d7d 100644 --- a/config.w32 +++ b/config.w32 @@ -727,6 +727,7 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\transport\\call_spine.cc " + "src\\core\\lib\\transport\\connectivity_state.cc " + "src\\core\\lib\\transport\\error_utils.cc " + + "src\\core\\lib\\transport\\interception_chain.cc " + "src\\core\\lib\\transport\\message.cc " + "src\\core\\lib\\transport\\metadata.cc " + "src\\core\\lib\\transport\\metadata_batch.cc " + diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 94651c55feb..530f61b07aa 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -176,6 +176,7 @@ Pod::Spec.new do |s| 'include/grpcpp/impl/service_type.h', 'include/grpcpp/impl/status.h', 'include/grpcpp/impl/sync.h', + 'include/grpcpp/passive_listener.h', 'include/grpcpp/resource_quota.h', 'include/grpcpp/security/audit_logging.h', 'include/grpcpp/security/auth_context.h', @@ -1212,6 +1213,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/batch_builder.h', 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.h', 'src/core/lib/transport/call_spine.h', @@ -1219,6 +1221,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/custom_metadata.h', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', @@ -2481,6 +2484,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/batch_builder.h', 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.h', 'src/core/lib/transport/call_spine.h', @@ -2488,6 +2492,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/custom_metadata.h', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 4e6d835dc2a..baff363da6c 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -168,6 +168,7 @@ Pod::Spec.new do |s| 'include/grpc/impl/propagation_bits.h', 'include/grpc/impl/slice_type.h', 'include/grpc/load_reporting.h', + 'include/grpc/passive_listener.h', 'include/grpc/slice.h', 'include/grpc/slice_buffer.h', 'include/grpc/status.h', @@ -1863,6 +1864,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.cc', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.cc', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.cc', @@ -1875,6 +1877,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/error_utils.cc', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.cc', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.cc', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.cc', @@ -3260,6 +3264,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/batch_builder.h', 'src/core/lib/transport/bdp_estimator.h', 'src/core/lib/transport/call_arena_allocator.h', + 'src/core/lib/transport/call_destination.h', 'src/core/lib/transport/call_filters.h', 'src/core/lib/transport/call_final_info.h', 'src/core/lib/transport/call_spine.h', @@ -3267,6 +3272,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/custom_metadata.h', 'src/core/lib/transport/error_utils.h', 'src/core/lib/transport/http2_errors.h', + 'src/core/lib/transport/interception_chain.h', 'src/core/lib/transport/message.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', diff --git a/grpc.gemspec b/grpc.gemspec index 53f5845e405..4a58496ff43 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -99,6 +99,7 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/impl/propagation_bits.h ) s.files += %w( include/grpc/impl/slice_type.h ) s.files += %w( include/grpc/load_reporting.h ) + s.files += %w( include/grpc/passive_listener.h ) s.files += %w( include/grpc/slice.h ) s.files += %w( include/grpc/slice_buffer.h ) s.files += %w( include/grpc/status.h ) @@ -1750,6 +1751,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/bdp_estimator.h ) s.files += %w( src/core/lib/transport/call_arena_allocator.cc ) s.files += %w( src/core/lib/transport/call_arena_allocator.h ) + s.files += %w( src/core/lib/transport/call_destination.h ) s.files += %w( src/core/lib/transport/call_filters.cc ) s.files += %w( src/core/lib/transport/call_filters.h ) s.files += %w( src/core/lib/transport/call_final_info.cc ) @@ -1762,6 +1764,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/error_utils.cc ) s.files += %w( src/core/lib/transport/error_utils.h ) s.files += %w( src/core/lib/transport/http2_errors.h ) + s.files += %w( src/core/lib/transport/interception_chain.cc ) + s.files += %w( src/core/lib/transport/interception_chain.h ) s.files += %w( src/core/lib/transport/message.cc ) s.files += %w( src/core/lib/transport/message.h ) s.files += %w( src/core/lib/transport/metadata.cc ) diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap index c9219532826..30427e21d05 100644 --- a/include/grpc/module.modulemap +++ b/include/grpc/module.modulemap @@ -38,6 +38,7 @@ header "byte_buffer.h" header "impl/propagation_bits.h" header "impl/slice_type.h" header "load_reporting.h" + header "passive_listener.h" header "slice.h" header "slice_buffer.h" header "status.h" diff --git a/include/grpc/passive_listener.h b/include/grpc/passive_listener.h new file mode 100644 index 00000000000..fffc789dba0 --- /dev/null +++ b/include/grpc/passive_listener.h @@ -0,0 +1,62 @@ +// Copyright 2024 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. +#ifndef GRPC_PASSIVE_LISTENER_H +#define GRPC_PASSIVE_LISTENER_H + +#include + +#include +#include +// #include + +namespace grpc_core { +class Server; + +namespace experimental { +class PassiveListenerImpl; + +/// -- EXPERIMENTAL API -- +/// Interface for used for Server Endpoint injection. +class PassiveListener { + public: + virtual ~PassiveListener() = default; + /// -- EXPERIMENTAL API -- + /// + /// Takes an Endpoint for an established connection, and treats it as if the + /// connection had been accepted by the server. + /// + /// The server must be started before endpoints can be accepted. + virtual absl::Status AcceptConnectedEndpoint( + std::unique_ptr + endpoint) = 0; + + /// -- EXPERIMENTAL API -- + /// + /// Takes a connected file descriptor, and treats it as if the server had + /// accepted the connection itself. + /// + /// Returns a failure status if the server's active EventEngine does not + /// support Endpoint creation from fds. + virtual absl::Status AcceptConnectedFd(int fd) = 0; +}; + +} // namespace experimental +} // namespace grpc_core + +absl::Status grpc_server_add_passive_listener( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener); + +#endif /* GRPC_PASSIVE_LISTENER_H */ diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h index 6e5cf4b7157..2cba30164ff 100644 --- a/include/grpc/support/log.h +++ b/include/grpc/support/log.h @@ -99,12 +99,6 @@ GPRAPI void gpr_assertion_failed(const char* filename, int line, } \ } while (0) -#ifndef NDEBUG -#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(x) -#else -#define GPR_DEBUG_ASSERT(x) GPR_ASSERT(true || (x)) -#endif - #ifdef __cplusplus } #endif diff --git a/include/grpcpp/passive_listener.h b/include/grpcpp/passive_listener.h new file mode 100644 index 00000000000..8def9592b5e --- /dev/null +++ b/include/grpcpp/passive_listener.h @@ -0,0 +1,27 @@ +// Copyright 2024 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. +#ifndef GRPCPP_PASSIVE_LISTENER_H +#define GRPCPP_PASSIVE_LISTENER_H + +#include + +namespace grpc { +namespace experimental { + +using grpc_core::experimental::PassiveListener; + +} // namespace experimental +} // namespace grpc + +#endif // GRPCPP_PASSIVE_LISTENER_H diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h index fe8c546190d..e3f5c2bbbfe 100644 --- a/include/grpcpp/security/server_credentials.h +++ b/include/grpcpp/security/server_credentials.h @@ -84,6 +84,7 @@ class ServerCredentials : private grpc::internal::GrpcLibrary { // Needed for access to AddPortToServer. friend class Server; // Needed for access to c_creds_. + friend class ServerBuilder; friend std::shared_ptr grpc::XdsServerCredentials( const std::shared_ptr& fallback_credentials); diff --git a/include/grpcpp/security/tls_credentials_options.h b/include/grpcpp/security/tls_credentials_options.h index 6adf9faac64..11c40f04086 100644 --- a/include/grpcpp/security/tls_credentials_options.h +++ b/include/grpcpp/security/tls_credentials_options.h @@ -103,6 +103,8 @@ class TlsCredentialsOptions { // call is covered by the cert that the peer presented. // We will perform such checks by default. This should be disabled if // verifiers other than the host name verifier is used. + // Deprecated: This function will be removed in the 1.66 release. This will be + // replaced by and handled within the custom verifier settings. void set_check_call_host(bool check_call_host); // Deprecated in favor of set_crl_provider. The @@ -111,6 +113,8 @@ class TlsCredentialsOptions { // If set, gRPC will read all hashed x.509 CRL files in the directory and // enforce the CRL files on all TLS handshakes. Only supported for OpenSSL // version > 1.1. + // Deprecated: This function will be removed in the 1.66 release. Use the + // set_crl_provider function instead. void set_crl_directory(const std::string& path); void set_crl_provider(std::shared_ptr crl_provider); @@ -184,6 +188,7 @@ class TlsServerCredentialsOptions final : public TlsCredentialsOptions { // WARNING: This API is extremely dangerous and should not be used. If the // server's trust bundle is too large, then the TLS server will be unable to // form a ServerHello, and hence will be unusable. + // Deprecated: This function will be removed in the 1.66 release. void set_send_client_ca_list(bool send_client_ca_list); private: diff --git a/include/grpcpp/server_builder.h b/include/grpcpp/server_builder.h index e6266a90d98..e66ca4301cd 100644 --- a/include/grpcpp/server_builder.h +++ b/include/grpcpp/server_builder.h @@ -25,13 +25,17 @@ #include #include +#include +#include #include #include #include #include #include #include +#include #include +#include #include #include #include @@ -291,6 +295,18 @@ class ServerBuilder { void EnableCallMetricRecording( experimental::ServerMetricRecorder* server_metric_recorder = nullptr); + // Creates a passive listener for Server Endpoint injection. + /// + /// \a PasiveListener lets applications provide pre-established connections + /// to gRPC Servers. The server will behave as if it accepted the connection + /// itself on its own listening addresses. + /// + /// This can be called multiple times to create passive listeners with + /// different server credentials. + ServerBuilder& AddPassiveListener( + std::shared_ptr creds, + std::unique_ptr& passive_listener); + private: ServerBuilder* builder_; }; @@ -364,6 +380,17 @@ class ServerBuilder { private: friend class grpc::testing::ServerBuilderPluginTest; + struct UnstartedPassiveListener { + std::weak_ptr + passive_listener; + std::shared_ptr credentials; + UnstartedPassiveListener( + std::weak_ptr listener, + std::shared_ptr creds) + : passive_listener(std::move(listener)), + credentials(std::move(creds)) {} + }; + struct SyncServerSettings { SyncServerSettings() : num_cqs(1), min_pollers(1), max_pollers(2), cq_timeout_msec(10000) {} @@ -388,6 +415,7 @@ class ServerBuilder { std::vector> options_; std::vector> services_; std::vector ports_; + std::vector unstarted_passive_listeners_; SyncServerSettings sync_server_settings_; diff --git a/package.xml b/package.xml index e7600613939..44f87605fa6 100644 --- a/package.xml +++ b/package.xml @@ -81,6 +81,7 @@ + @@ -1732,6 +1733,7 @@ + @@ -1744,6 +1746,8 @@ + + diff --git a/src/core/BUILD b/src/core/BUILD index ec15ddb027c..a9580c2aaa6 100644 --- a/src/core/BUILD +++ b/src/core/BUILD @@ -48,6 +48,25 @@ grpc_cc_library( language = "c++", ) +grpc_cc_library( + name = "dump_args", + srcs = [ + "lib/gprpp/dump_args.cc", + ], + hdrs = [ + "lib/gprpp/dump_args.h", + ], + external_deps = [ + "absl/functional:any_invocable", + "absl/log:check", + "absl/strings", + ], + language = "c++", + deps = [ + "//:gpr_platform", + ], +) + grpc_cc_library( name = "slice_cast", hdrs = [ @@ -197,6 +216,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -395,6 +415,7 @@ grpc_cc_library( "lib/gprpp/validation_errors.h", ], external_deps = [ + "absl/log:log", "absl/status", "absl/strings", ], @@ -511,7 +532,10 @@ grpc_cc_library( grpc_cc_library( name = "map_pipe", - external_deps = ["absl/status"], + external_deps = [ + "absl/log:log", + "absl/status", + ], language = "c++", public_hdrs = [ "lib/promise/map_pipe.h", @@ -540,6 +564,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", ], @@ -639,7 +664,10 @@ grpc_cc_library( grpc_cc_library( name = "promise_like", - external_deps = ["absl/meta:type_traits"], + external_deps = [ + "absl/functional:any_invocable", + "absl/meta:type_traits", + ], language = "c++", public_hdrs = [ "lib/promise/detail/promise_like.h", @@ -754,6 +782,7 @@ grpc_cc_library( name = "join_state", external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", public_hdrs = [ @@ -843,6 +872,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -982,6 +1012,7 @@ grpc_cc_library( name = "latch", external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -1000,6 +1031,7 @@ grpc_cc_library( name = "inter_activity_latch", external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/strings", ], language = "c++", @@ -1022,6 +1054,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", "absl/types:optional", @@ -1045,6 +1078,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", "absl/types:optional", "absl/types:variant", @@ -1156,6 +1190,7 @@ grpc_cc_library( name = "for_each", external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", ], @@ -1178,6 +1213,7 @@ grpc_cc_library( name = "ref_counted", external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", public_hdrs = ["lib/gprpp/ref_counted.h"], @@ -1194,6 +1230,7 @@ grpc_cc_library( name = "dual_ref_counted", external_deps = [ "absl/log:check", + "absl/log:log", ], language = "c++", public_hdrs = ["lib/gprpp/dual_ref_counted.h"], @@ -1389,6 +1426,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:flat_hash_set", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -1439,6 +1477,9 @@ grpc_cc_library( hdrs = [ "lib/resource_quota/arena.h", ], + external_deps = [ + "absl/log:log", + ], visibility = [ "@grpc:alt_grpc_base_legacy", ], @@ -1538,6 +1579,9 @@ grpc_cc_library( hdrs = [ "lib/slice/slice_refcount.h", ], + external_deps = [ + "absl/log:log", + ], public_hdrs = [ "//:include/grpc/slice.h", ], @@ -1605,6 +1649,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -1632,6 +1677,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:str_format", ], visibility = ["@grpc:alt_grpc_base_legacy"], @@ -1653,6 +1699,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings:str_format", "absl/types:optional", ], @@ -1734,6 +1781,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "//:config_vars", @@ -1883,6 +1931,7 @@ grpc_cc_library( "absl/container:flat_hash_set", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/time", "absl/types:optional", ], @@ -1933,6 +1982,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/time", "absl/types:optional", ], @@ -2090,6 +2140,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2196,6 +2247,7 @@ grpc_cc_library( ], external_deps = [ "absl/functional:any_invocable", + "absl/log:log", "absl/status", "absl/types:optional", ], @@ -2220,6 +2272,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2281,6 +2334,7 @@ grpc_cc_library( external_deps = [ "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2313,6 +2367,7 @@ grpc_cc_library( external_deps = [ "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2340,6 +2395,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2376,6 +2432,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2418,6 +2475,7 @@ grpc_cc_library( hdrs = ["lib/event_engine/windows/windows_engine.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2472,6 +2530,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -2501,6 +2560,7 @@ grpc_cc_library( "absl/cleanup", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings:str_format", ], @@ -2529,6 +2589,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings:str_format", @@ -2563,6 +2624,7 @@ grpc_cc_library( external_deps = [ "absl/container:flat_hash_map", "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", ], @@ -2597,6 +2659,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2623,6 +2686,9 @@ grpc_cc_library( hdrs = [ "lib/event_engine/trace.h", ], + external_deps = [ + "absl/log:log", + ], deps = [ "//:gpr", "//:gpr_platform", @@ -2813,6 +2879,7 @@ grpc_cc_library( "absl/functional:any_invocable", "absl/hash", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -2869,6 +2936,7 @@ grpc_cc_library( hdrs = ["lib/transport/bdp_estimator.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -3054,6 +3122,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/strings", "absl/types:optional", ], @@ -3064,6 +3133,7 @@ grpc_cc_library( "channel_fwd", "channel_stack_trace", "channel_stack_type", + "interception_chain", "//:channel_stack_builder", "//:debug_location", "//:gpr", @@ -3081,6 +3151,7 @@ grpc_cc_library( deps = [ "channel_args", "//:channelz", + "//:event_engine_base_hdrs", "//:gpr_platform", ], ) @@ -3130,7 +3201,10 @@ grpc_cc_library( hdrs = [ "service_config/service_config_parser.h", ], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", deps = [ "channel_args", @@ -3159,6 +3233,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/strings", "absl/strings:str_format", @@ -3334,6 +3409,7 @@ grpc_cc_library( "client_channel/retry_service_config.h", ], external_deps = [ + "absl/log:log", "absl/strings", "absl/types:optional", ], @@ -3384,6 +3460,7 @@ grpc_cc_library( "client_channel/backup_poller.h", ], external_deps = [ + "absl/log:log", "absl/status", ], language = "c++", @@ -3407,6 +3484,7 @@ grpc_cc_library( "service_config/service_config_channel_arg_filter.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", @@ -3493,6 +3571,7 @@ grpc_cc_library( hdrs = ["load_balancing/lb_policy_registry.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3603,6 +3682,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3742,6 +3822,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -3789,6 +3870,7 @@ grpc_cc_library( "lib/security/authorization/grpc_server_authz_filter.h", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3831,6 +3913,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/container:flat_hash_map", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3864,6 +3947,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -3944,6 +4028,9 @@ grpc_cc_library( hdrs = [ "tsi/local_transport_security.h", ], + external_deps = [ + "absl/log:log", + ], language = "c++", deps = [ "//:event_engine_base_hdrs", @@ -3965,6 +4052,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4012,6 +4100,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/strings:str_format", @@ -4057,6 +4146,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -4139,6 +4229,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:bind_front", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4225,6 +4316,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4287,6 +4379,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4333,6 +4426,7 @@ grpc_cc_library( "lib/http/httpcli_ssl_credentials.h", ], external_deps = [ + "absl/log:log", "absl/status", "absl/strings", "absl/types:optional", @@ -4407,6 +4501,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4557,6 +4652,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -4638,6 +4734,7 @@ grpc_cc_library( "ext/filters/message_size/message_size_filter.h", ], external_deps = [ + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/strings:str_format", @@ -4686,6 +4783,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -4825,6 +4923,7 @@ grpc_cc_library( "absl/container:inlined_vector", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -4942,6 +5041,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/hash", "absl/log:check", + "absl/log:log", "absl/random", "absl/status", "absl/status:statusor", @@ -5076,6 +5176,7 @@ grpc_cc_library( "absl/cleanup", "absl/functional:bind_front", "absl/log:check", + "absl/log:log", "absl/memory", "absl/random", "absl/status", @@ -5260,6 +5361,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5338,6 +5440,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5398,6 +5501,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5448,6 +5552,7 @@ grpc_cc_library( "load_balancing/xds/xds_cluster_manager.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5491,6 +5596,7 @@ grpc_cc_library( "load_balancing/xds/xds_wrr_locality.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5560,6 +5666,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5607,6 +5714,7 @@ grpc_cc_library( external_deps = [ "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", @@ -5644,6 +5752,7 @@ grpc_cc_library( external_deps = [ "absl/algorithm:container", "absl/log:check", + "absl/log:log", "absl/random", "absl/status", "absl/status:statusor", @@ -5730,7 +5839,10 @@ grpc_cc_library( hdrs = [ "lib/transport/connectivity_state.h", ], - external_deps = ["absl/status"], + external_deps = [ + "absl/log:log", + "absl/status", + ], deps = [ "closure", "error", @@ -5765,6 +5877,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:inlined_vector", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -5815,6 +5928,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -5868,6 +5982,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -5938,6 +6053,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -5987,6 +6103,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6035,6 +6152,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -6084,6 +6202,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6145,6 +6264,7 @@ grpc_cc_library( ], external_deps = [ "absl/container:inlined_vector", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6189,6 +6309,7 @@ grpc_cc_library( "ext/filters/backend_metrics/backend_metric_filter.h", ], external_deps = [ + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -6229,6 +6350,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6293,6 +6415,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/cleanup", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6334,7 +6457,10 @@ grpc_cc_library( hdrs = [ "resolver/dns/dns_resolver_plugin.h", ], - external_deps = ["absl/strings"], + external_deps = [ + "absl/log:log", + "absl/strings", + ], language = "c++", deps = [ "experiments", @@ -6358,6 +6484,7 @@ grpc_cc_library( ], external_deps = [ "absl/functional:bind_front", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6391,6 +6518,7 @@ grpc_cc_library( "resolver/sockaddr/sockaddr_resolver.cc", ], external_deps = [ + "absl/log:log", "absl/status:statusor", "absl/strings", ], @@ -6415,6 +6543,7 @@ grpc_cc_library( "resolver/binder/binder_resolver.cc", ], external_deps = [ + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6476,6 +6605,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/container:flat_hash_set", "absl/log:check", + "absl/log:log", "absl/strings", ], language = "c++", @@ -6499,6 +6629,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/meta:type_traits", "absl/random", "absl/status", @@ -6560,6 +6691,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", @@ -6627,6 +6759,7 @@ grpc_cc_library( external_deps = [ "absl/functional:function_ref", "absl/log:check", + "absl/log:log", "absl/status", "absl/strings", "absl/strings:str_format", @@ -6821,6 +6954,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings:str_format", @@ -6878,6 +7012,7 @@ grpc_cc_library( external_deps = [ "absl/base:core_headers", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6892,6 +7027,8 @@ grpc_cc_library( "connection_quota", "error", "error_utils", + "event_engine_extensions", + "event_engine_query_extensions", "grpc_insecure_credentials", "handshaker_registry", "iomgr_fwd", @@ -6937,6 +7074,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -6954,6 +7092,7 @@ grpc_cc_library( "experiments", "iomgr_fwd", "metadata_batch", + "resource_quota", "slice", "slice_buffer", "status_helper", @@ -7062,6 +7201,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -7115,6 +7255,7 @@ grpc_cc_library( "ext/filters/logging/logging_filter.h", ], external_deps = [ + "absl/log:log", "absl/numeric:int128", "absl/random", "absl/random:distributions", @@ -7193,7 +7334,10 @@ grpc_cc_library( hdrs = [ "ext/transport/chaotic_good/chaotic_good_transport.h", ], - external_deps = ["absl/random"], + external_deps = [ + "absl/log:log", + "absl/random", + ], language = "c++", deps = [ "chaotic_good_frame", @@ -7222,6 +7366,7 @@ grpc_cc_library( "absl/base:core_headers", "absl/container:flat_hash_map", "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", @@ -7280,6 +7425,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", @@ -7365,6 +7511,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "call_final_info", @@ -7475,6 +7622,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "1999", @@ -7612,6 +7760,7 @@ grpc_cc_library( external_deps = [ "absl/container:flat_hash_map", "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", @@ -7677,6 +7826,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "absl/random", "absl/random:bit_gen_ref", "absl/status", diff --git a/src/core/ext/filters/logging/logging_filter.cc b/src/core/ext/filters/logging/logging_filter.cc index 1c76e64b06a..587e87ff506 100644 --- a/src/core/ext/filters/logging/logging_filter.cc +++ b/src/core/ext/filters/logging/logging_filter.cc @@ -539,11 +539,11 @@ void RegisterLoggingFilter(LoggingSink* sink) { g_logging_sink = sink; CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) { builder->channel_init() - ->RegisterFilter(GRPC_SERVER_CHANNEL) + ->RegisterV2Filter(GRPC_SERVER_CHANNEL) // TODO(yashykt) : Figure out a good place to place this channel arg .IfChannelArg("grpc.experimental.enable_observability", true); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_CHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_CHANNEL) // TODO(yashykt) : Figure out a good place to place this channel arg .IfChannelArg("grpc.experimental.enable_observability", true); }); diff --git a/src/core/ext/transport/binder/server/binder_server.cc b/src/core/ext/transport/binder/server/binder_server.cc index faf1641d7d1..6f4d932f436 100644 --- a/src/core/ext/transport/binder/server/binder_server.cc +++ b/src/core/ext/transport/binder/server/binder_server.cc @@ -160,7 +160,7 @@ class BinderServerListener : public Server::ListenerInterface { on_destroy_done_ = on_destroy_done; } - void Orphan() override { delete this; } + void Orphan() override { Unref(); } ~BinderServerListener() override { ExecCtx::Get()->Flush(); @@ -240,9 +240,8 @@ bool AddBinderPort(const std::string& addr, grpc_server* server, } std::string conn_id = addr.substr(kBinderUriScheme.size()); Server* core_server = Server::FromC(server); - core_server->AddListener( - OrphanablePtr(new BinderServerListener( - core_server, conn_id, std::move(factory), security_policy))); + core_server->AddListener(MakeOrphanable( + core_server, conn_id, std::move(factory), security_policy)); return true; } diff --git a/src/core/ext/transport/binder/transport/binder_transport.cc b/src/core/ext/transport/binder/transport/binder_transport.cc index b5e32e913b7..65512675d96 100644 --- a/src/core/ext/transport/binder/transport/binder_transport.cc +++ b/src/core/ext/transport/binder/transport/binder_transport.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/strings/substitute.h" @@ -141,7 +142,7 @@ static void AssignMetadata(grpc_metadata_batch* mb, static void cancel_stream_locked(grpc_binder_transport* transport, grpc_binder_stream* stream, grpc_error_handle error) { - gpr_log(GPR_INFO, "cancel_stream_locked"); + LOG(INFO) << "cancel_stream_locked"; if (!stream->is_closed) { CHECK(stream->cancel_self_error.ok()); stream->is_closed = true; @@ -200,7 +201,7 @@ static void recv_initial_metadata_locked(void* arg, CHECK(stream->recv_initial_metadata); CHECK(stream->recv_initial_metadata_ready); if (!args->initial_metadata.ok()) { - gpr_log(GPR_ERROR, "Failed to parse initial metadata"); + LOG(ERROR) << "Failed to parse initial metadata"; return absl_status_to_grpc_error(args->initial_metadata.status()); } if (!stream->is_client) { @@ -237,11 +238,11 @@ static void recv_message_locked(void* arg, grpc_error_handle /*error*/) { CHECK(stream->recv_message); CHECK(stream->recv_message_ready); if (!args->message.ok()) { - gpr_log(GPR_ERROR, "Failed to receive message"); + LOG(ERROR) << "Failed to receive message"; if (args->message.status().message() == grpc_binder::TransportStreamReceiver:: kGrpcBinderTransportCancelledGracefully) { - gpr_log(GPR_ERROR, "message cancelled gracefully"); + LOG(ERROR) << "message cancelled gracefully"; // Cancelled because we've already received trailing metadata. // It's not an error in this case. return absl::OkStatus(); @@ -281,13 +282,13 @@ static void recv_trailing_metadata_locked(void* arg, CHECK(stream->recv_trailing_metadata); CHECK(stream->recv_trailing_metadata_finished); if (!args->trailing_metadata.ok()) { - gpr_log(GPR_ERROR, "Failed to receive trailing metadata"); + LOG(ERROR) << "Failed to receive trailing metadata"; return absl_status_to_grpc_error(args->trailing_metadata.status()); } if (!stream->is_client) { // Client will not send non-empty trailing metadata. if (!args->trailing_metadata.value().empty()) { - gpr_log(GPR_ERROR, "Server receives non-empty trailing metadata."); + LOG(ERROR) << "Server receives non-empty trailing metadata."; return absl::CancelledError(); } } else { @@ -371,7 +372,7 @@ class MetadataEncoder { static void accept_stream_locked(void* gt, grpc_error_handle /*error*/) { grpc_binder_transport* transport = static_cast(gt); if (transport->accept_stream_fn) { - gpr_log(GPR_INFO, "Accepting a stream"); + LOG(INFO) << "Accepting a stream"; // must pass in a non-null value. (*transport->accept_stream_fn)(transport->accept_stream_user_data, transport, transport); @@ -449,7 +450,7 @@ static void perform_stream_op_locked(void* stream_op, std::make_unique(tx_code, transport->is_client); if (op->send_initial_metadata) { - gpr_log(GPR_INFO, "send_initial_metadata"); + LOG(INFO) << "send_initial_metadata"; grpc_binder::Metadata init_md; auto batch = op->payload->send_initial_metadata.send_initial_metadata; @@ -459,12 +460,12 @@ static void perform_stream_op_locked(void* stream_op, tx->SetPrefix(init_md); } if (op->send_message) { - gpr_log(GPR_INFO, "send_message"); + LOG(INFO) << "send_message"; tx->SetData(op->payload->send_message.send_message->JoinIntoString()); } if (op->send_trailing_metadata) { - gpr_log(GPR_INFO, "send_trailing_metadata"); + LOG(INFO) << "send_trailing_metadata"; auto batch = op->payload->send_trailing_metadata.send_trailing_metadata; grpc_binder::Metadata trailing_metadata; @@ -477,7 +478,7 @@ static void perform_stream_op_locked(void* stream_op, tx->SetSuffix(trailing_metadata); } if (op->recv_initial_metadata) { - gpr_log(GPR_INFO, "recv_initial_metadata"); + LOG(INFO) << "recv_initial_metadata"; stream->recv_initial_metadata_ready = op->payload->recv_initial_metadata.recv_initial_metadata_ready; stream->recv_initial_metadata = @@ -500,7 +501,7 @@ static void perform_stream_op_locked(void* stream_op, }); } if (op->recv_message) { - gpr_log(GPR_INFO, "recv_message"); + LOG(INFO) << "recv_message"; stream->recv_message_ready = op->payload->recv_message.recv_message_ready; stream->recv_message = op->payload->recv_message.recv_message; stream->call_failed_before_recv_message = @@ -523,7 +524,7 @@ static void perform_stream_op_locked(void* stream_op, }); } if (op->recv_trailing_metadata) { - gpr_log(GPR_INFO, "recv_trailing_metadata"); + LOG(INFO) << "recv_trailing_metadata"; stream->recv_trailing_metadata_finished = op->payload->recv_trailing_metadata.recv_trailing_metadata_ready; stream->recv_trailing_metadata = @@ -571,7 +572,7 @@ static void perform_stream_op_locked(void* stream_op, if (op->on_complete != nullptr) { grpc_core::ExecCtx::Run(DEBUG_LOCATION, op->on_complete, absl_status_to_grpc_error(status)); - gpr_log(GPR_INFO, "on_complete closure scheduled"); + LOG(INFO) << "on_complete closure scheduled"; } GRPC_BINDER_STREAM_UNREF(stream, "perform_stream_op"); } diff --git a/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc b/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc index 8595f8bf149..02cd6cf09cd 100644 --- a/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc +++ b/src/core/ext/transport/binder/wire_format/wire_reader_impl.cc @@ -26,6 +26,7 @@ #include "absl/functional/any_invocable.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/status/statusor.h" @@ -136,9 +137,9 @@ void WireReaderImpl::SendSetupTransport(Binder* binder) { std::unique_ptr WireReaderImpl::RecvSetupTransport() { // TODO(b/191941760): avoid blocking, handle wire_writer_noti lifetime // better - gpr_log(GPR_DEBUG, "start waiting for noti"); + VLOG(2) << "start waiting for noti"; connection_noti_.WaitForNotification(); - gpr_log(GPR_DEBUG, "end waiting for noti"); + VLOG(2) << "end waiting for noti"; return std::move(other_end_binder_); } @@ -153,8 +154,8 @@ absl::Status WireReaderImpl::ProcessTransaction(transaction_code_t code, BinderTransportTxCode::SETUP_TRANSPORT) && code <= static_cast( BinderTransportTxCode::PING_RESPONSE))) { - gpr_log(GPR_INFO, - "Received unknown control message. Shutdown transport gracefully."); + LOG(INFO) + << "Received unknown control message. Shutdown transport gracefully."; // TODO(waynetu): Shutdown transport gracefully. return absl::OkStatus(); } @@ -210,8 +211,8 @@ absl::Status WireReaderImpl::ProcessTransaction(transaction_code_t code, break; } case BinderTransportTxCode::SHUTDOWN_TRANSPORT: { - gpr_log(GPR_ERROR, - "Received SHUTDOWN_TRANSPORT request but not implemented yet."); + LOG(ERROR) + << "Received SHUTDOWN_TRANSPORT request but not implemented yet."; return absl::UnimplementedError("SHUTDOWN_TRANSPORT"); } case BinderTransportTxCode::ACKNOWLEDGE_BYTES: { @@ -286,16 +287,16 @@ absl::Status WireReaderImpl::ProcessStreamingTransaction( tx_process_result.ToString().c_str()); // Something went wrong when receiving transaction. Cancel failed requests. if (cancellation_flags & kFlagPrefix) { - gpr_log(GPR_INFO, "cancelling initial metadata"); + LOG(INFO) << "cancelling initial metadata"; transport_stream_receiver_->NotifyRecvInitialMetadata(code, tx_process_result); } if (cancellation_flags & kFlagMessageData) { - gpr_log(GPR_INFO, "cancelling message data"); + LOG(INFO) << "cancelling message data"; transport_stream_receiver_->NotifyRecvMessage(code, tx_process_result); } if (cancellation_flags & kFlagSuffix) { - gpr_log(GPR_INFO, "cancelling trailing metadata"); + LOG(INFO) << "cancelling trailing metadata"; transport_stream_receiver_->NotifyRecvTrailingMetadata( code, tx_process_result, 0); } @@ -338,7 +339,7 @@ absl::Status WireReaderImpl::ProcessStreamingTransactionImpl( // intended behavior. // TODO(waynetu): What should be returned here? if (flags == 0) { - gpr_log(GPR_INFO, "[WARNING] Receive empty transaction. Ignored."); + LOG(INFO) << "[WARNING] Receive empty transaction. Ignored."; return absl::OkStatus(); } diff --git a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc index e00bcc1b379..7dd94de3090 100644 --- a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc +++ b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.cc @@ -103,8 +103,8 @@ absl::StatusOr ChaoticGoodServerListener::Bind( str.ok() ? str->c_str() : str.status().ToString().c_str()); } EventEngine::Listener::AcceptCallback accept_cb = - [self = Ref()](std::unique_ptr ep, - MemoryAllocator) { + [self = RefAsSubclass()]( + std::unique_ptr ep, MemoryAllocator) { ExecCtx exec_ctx; MutexLock lock(&self->mu_); if (self->shutdown_) return; @@ -149,7 +149,8 @@ absl::Status ChaoticGoodServerListener::StartListening() { ChaoticGoodServerListener::ActiveConnection::ActiveConnection( RefCountedPtr listener, std::unique_ptr endpoint) - : memory_allocator_(listener->memory_allocator_), listener_(listener) { + : memory_allocator_(listener->memory_allocator_), + listener_(std::move(listener)) { handshaking_state_ = MakeRefCounted(Ref()); handshaking_state_->Start(std::move(endpoint)); } diff --git a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h index 404bbbf946d..0479016c15b 100644 --- a/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h +++ b/src/core/ext/transport/chaotic_good/server/chaotic_good_server.h @@ -49,9 +49,7 @@ namespace grpc_core { namespace chaotic_good { -class ChaoticGoodServerListener final - : public Server::ListenerInterface, - public RefCounted { +class ChaoticGoodServerListener final : public Server::ListenerInterface { public: static absl::AnyInvocable DefaultConnectionIDGenerator() { return [bitgen = absl::BitGen()]() mutable { diff --git a/src/core/ext/transport/chaotic_good/server_transport.cc b/src/core/ext/transport/chaotic_good/server_transport.cc index c139c6e44e0..98fbf4e915e 100644 --- a/src/core/ext/transport/chaotic_good/server_transport.cc +++ b/src/core/ext/transport/chaotic_good/server_transport.cc @@ -235,37 +235,27 @@ auto ChaoticGoodServerTransport::DeserializeAndPushFragmentToNewCall( FrameHeader frame_header, BufferPair buffers, ChaoticGoodTransport& transport) { ClientFragmentFrame fragment_frame; - ScopedArenaPtr arena(acceptor_->CreateArena()); + ScopedArenaPtr arena(call_arena_allocator_->MakeArena()); absl::Status status = transport.DeserializeFrame( frame_header, std::move(buffers), arena.get(), fragment_frame, FrameLimits{1024 * 1024 * 1024, aligned_bytes_ - 1}); absl::optional call_initiator; if (status.ok()) { - auto create_call_result = acceptor_->CreateCall( - std::move(fragment_frame.headers), arena.release()); - if (grpc_chaotic_good_trace.enabled()) { - gpr_log(GPR_INFO, - "CHAOTIC_GOOD: DeserializeAndPushFragmentToNewCall: " - "create_call_result=%s", - create_call_result.ok() - ? "ok" - : create_call_result.status().ToString().c_str()); - } - if (create_call_result.ok()) { - call_initiator.emplace(std::move(*create_call_result)); - auto add_result = NewStream(frame_header.stream_id, *call_initiator); - if (add_result.ok()) { - call_initiator->SpawnGuarded( - "server-write", [this, stream_id = frame_header.stream_id, - call_initiator = *call_initiator]() { - return CallOutboundLoop(stream_id, call_initiator); - }); - } else { - call_initiator.reset(); - status = add_result; - } + auto call = + MakeCallPair(std::move(fragment_frame.headers), event_engine_.get(), + arena.release(), call_arena_allocator_, nullptr); + call_initiator.emplace(std::move(call.initiator)); + auto add_result = NewStream(frame_header.stream_id, *call_initiator); + if (add_result.ok()) { + call_destination_->StartCall(std::move(call.handler)); + call_initiator->SpawnGuarded( + "server-write", [this, stream_id = frame_header.stream_id, + call_initiator = *call_initiator]() { + return CallOutboundLoop(stream_id, call_initiator); + }); } else { - status = create_call_result.status(); + call_initiator.reset(); + status = add_result; } } return MaybePushFragmentIntoCall(std::move(call_initiator), std::move(status), @@ -366,10 +356,13 @@ ChaoticGoodServerTransport::ChaoticGoodServerTransport( PromiseEndpoint data_endpoint, std::shared_ptr event_engine, HPackParser hpack_parser, HPackCompressor hpack_encoder) - : outgoing_frames_(4), - allocator_(args.GetObject() - ->memory_quota() - ->CreateMemoryAllocator("chaotic-good")) { + : call_arena_allocator_(MakeRefCounted( + args.GetObject() + ->memory_quota() + ->CreateMemoryAllocator("chaotic-good"), + 1024)), + event_engine_(event_engine), + outgoing_frames_(4) { auto transport = MakeRefCounted( std::move(control_endpoint), std::move(data_endpoint), std::move(hpack_parser), std::move(hpack_encoder)); @@ -381,20 +374,25 @@ ChaoticGoodServerTransport::ChaoticGoodServerTransport( OnTransportActivityDone("reader")); } -void ChaoticGoodServerTransport::SetAcceptor(Acceptor* acceptor) { - CHECK_EQ(acceptor_, nullptr); - CHECK_NE(acceptor, nullptr); - acceptor_ = acceptor; +void ChaoticGoodServerTransport::SetCallDestination( + RefCountedPtr call_destination) { + CHECK(call_destination_ == nullptr); + CHECK(call_destination != nullptr); + call_destination_ = call_destination; got_acceptor_.Set(); } -ChaoticGoodServerTransport::~ChaoticGoodServerTransport() { - if (writer_ != nullptr) { - writer_.reset(); - } - if (reader_ != nullptr) { - reader_.reset(); +void ChaoticGoodServerTransport::Orphan() { + ActivityPtr writer; + ActivityPtr reader; + { + MutexLock lock(&mu_); + writer = std::move(writer_); + reader = std::move(reader_); } + writer.reset(); + reader.reset(); + Unref(); } void ChaoticGoodServerTransport::AbortWithError() { diff --git a/src/core/ext/transport/chaotic_good/server_transport.h b/src/core/ext/transport/chaotic_good/server_transport.h index a34ac92b73e..140641abcf6 100644 --- a/src/core/ext/transport/chaotic_good/server_transport.h +++ b/src/core/ext/transport/chaotic_good/server_transport.h @@ -86,7 +86,6 @@ class ChaoticGoodServerTransport final : public ServerTransport { std::shared_ptr event_engine, HPackParser hpack_parser, HPackCompressor hpack_encoder); - ~ChaoticGoodServerTransport() override; FilterStackTransport* filter_stack_transport() override { return nullptr; } ClientTransport* client_transport() override { return nullptr; } @@ -96,9 +95,10 @@ class ChaoticGoodServerTransport final : public ServerTransport { void SetPollsetSet(grpc_stream*, grpc_pollset_set*) override {} void PerformOp(grpc_transport_op*) override; grpc_endpoint* GetEndpoint() override { return nullptr; } - void Orphan() override { Unref(); } + void Orphan() override; - void SetAcceptor(Acceptor* acceptor) override; + void SetCallDestination( + RefCountedPtr call_destination) override; void AbortWithError(); private: @@ -137,7 +137,10 @@ class ChaoticGoodServerTransport final : public ServerTransport { auto PushFragmentIntoCall(CallInitiator call_initiator, ClientFragmentFrame frame, uint32_t stream_id); - Acceptor* acceptor_ = nullptr; + RefCountedPtr call_destination_; + const RefCountedPtr call_arena_allocator_; + const std::shared_ptr + event_engine_; InterActivityLatch got_acceptor_; MpscReceiver outgoing_frames_; // Assigned aligned bytes from setting frame. @@ -146,7 +149,6 @@ class ChaoticGoodServerTransport final : public ServerTransport { // Map of stream incoming server frames, key is stream_id. StreamMap stream_map_ ABSL_GUARDED_BY(mu_); uint32_t last_seen_new_stream_id_ = 0; - grpc_event_engine::experimental::MemoryAllocator allocator_; ActivityPtr writer_ ABSL_GUARDED_BY(mu_); ActivityPtr reader_ ABSL_GUARDED_BY(mu_); ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(mu_){ diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 9b7770e4930..1c2ab26dc24 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,8 @@ #include "src/core/lib/config/core_configuration.h" #include "src/core/lib/debug/trace.h" #include "src/core/lib/event_engine/channel_args_endpoint_config.h" +#include "src/core/lib/event_engine/extensions/supports_fd.h" +#include "src/core/lib/event_engine/query_extensions.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" @@ -67,6 +70,7 @@ #include "src/core/lib/gprpp/unique_type_name.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/event_engine_shims/endpoint.h" #include "src/core/lib/iomgr/iomgr_fwd.h" #include "src/core/lib/iomgr/pollset_set.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -93,9 +97,11 @@ #endif // GPR_SUPPORT_CHANNELS_FROM_FD namespace grpc_core { -namespace { -using ::grpc_event_engine::experimental::EventEngine; +using grpc_event_engine::experimental::ChannelArgsEndpointConfig; +using grpc_event_engine::experimental::EventEngine; +using grpc_event_engine::experimental::EventEngineSupportsFdExtension; +using grpc_event_engine::experimental::QueryExtension; const char kUnixUriPrefix[] = "unix:"; const char kUnixAbstractUriPrefix[] = "unix-abstract:"; @@ -112,14 +118,23 @@ class Chttp2ServerListener : public Server::ListenerInterface { Server* server, const char* name, const ChannelArgs& args, Chttp2ServerArgsModifier args_modifier); + static Chttp2ServerListener* CreateForPassiveListener( + Server* server, const ChannelArgs& args, + std::shared_ptr passive_listener); + // Do not instantiate directly. Use one of the factory methods above. Chttp2ServerListener(Server* server, const ChannelArgs& args, - Chttp2ServerArgsModifier args_modifier); + Chttp2ServerArgsModifier args_modifier, + grpc_server_config_fetcher* config_fetcher, + std::shared_ptr + passive_listener = nullptr); ~Chttp2ServerListener() override; void Start(Server* server, const std::vector* pollsets) override; + void AcceptConnectedEndpoint(std::unique_ptr endpoint); + channelz::ListenSocketNode* channelz_listen_socket_node() const override { return channelz_listen_socket_.get(); } @@ -129,6 +144,8 @@ class Chttp2ServerListener : public Server::ListenerInterface { void Orphan() override; private: + friend class experimental::PassiveListenerImpl; + class ConfigFetcherWatcher : public grpc_server_config_fetcher::WatcherInterface { public: @@ -235,34 +252,8 @@ class Chttp2ServerListener : public Server::ListenerInterface { static void DestroyListener(Server* /*server*/, void* arg, grpc_closure* destroy_done); - // The interface required by RefCountedPtr<> has been manually implemented - // here to take a ref on tcp_server_ instead. Note that, the handshaker - // needs tcp_server_ to exist for the lifetime of the handshake since it's - // needed by acceptor. Sharing refs between the listener and tcp_server_ is - // just an optimization to avoid taking additional refs on the listener, - // since TcpServerShutdownComplete already holds a ref to the listener. - void IncrementRefCount() { grpc_tcp_server_ref(tcp_server_); } - void IncrementRefCount(const DebugLocation& /* location */, - const char* /* reason */) { - IncrementRefCount(); - } - - GRPC_MUST_USE_RESULT RefCountedPtr Ref() { - IncrementRefCount(); - return RefCountedPtr(this); - } - GRPC_MUST_USE_RESULT RefCountedPtr Ref( - const DebugLocation& /* location */, const char* /* reason */) { - return Ref(); - } - - void Unref() { grpc_tcp_server_unref(tcp_server_); } - void Unref(const DebugLocation& /* location */, const char* /* reason */) { - Unref(); - } - - Server* const server_; - grpc_tcp_server* tcp_server_; + Server* const server_ = nullptr; + grpc_tcp_server* tcp_server_ = nullptr; grpc_resolved_address resolved_address_; Chttp2ServerArgsModifier const args_modifier_; ConfigFetcherWatcher* config_fetcher_watcher_ = nullptr; @@ -285,6 +276,10 @@ class Chttp2ServerListener : public Server::ListenerInterface { RefCountedPtr channelz_listen_socket_; MemoryQuotaRefPtr memory_quota_; ConnectionQuotaRefPtr connection_quota_; + grpc_server_config_fetcher* config_fetcher_ = nullptr; + // TODO(yashykt): consider using absl::variant<> to minimize memory usage for + // disjoint cases where different fields are used. + std::shared_ptr passive_listener_; }; // @@ -381,13 +376,17 @@ Chttp2ServerListener::ActiveConnection::HandshakingState::HandshakingState( handshake_mgr_(MakeRefCounted()), deadline_(GetConnectionDeadline(args)), interested_parties_(grpc_pollset_set_create()) { - grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_); + if (accepting_pollset != nullptr) { + grpc_pollset_set_add_pollset(interested_parties_, accepting_pollset_); + } CoreConfiguration::Get().handshaker_registry().AddHandshakers( HANDSHAKER_SERVER, args, interested_parties_, handshake_mgr_.get()); } Chttp2ServerListener::ActiveConnection::HandshakingState::~HandshakingState() { - grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_); + if (accepting_pollset_ != nullptr) { + grpc_pollset_set_del_pollset(interested_parties_, accepting_pollset_); + } grpc_pollset_set_destroy(interested_parties_); gpr_free(acceptor_); } @@ -589,7 +588,11 @@ Chttp2ServerListener::ActiveConnection::ActiveConnection( grpc_schedule_on_exec_ctx); } -Chttp2ServerListener::ActiveConnection::~ActiveConnection() {} +Chttp2ServerListener::ActiveConnection::~ActiveConnection() { + if (listener_ != nullptr && listener_->tcp_server_ != nullptr) { + grpc_tcp_server_unref(listener_->tcp_server_); + } +} void Chttp2ServerListener::ActiveConnection::Orphan() { OrphanablePtr handshaking_state; @@ -637,6 +640,9 @@ void Chttp2ServerListener::ActiveConnection::Start( const ChannelArgs& args) { RefCountedPtr handshaking_state_ref; listener_ = std::move(listener); + if (listener_->tcp_server_ != nullptr) { + grpc_tcp_server_ref(listener_->tcp_server_); + } { ReleasableMutexLock lock(&mu_); if (shutdown_) { @@ -709,83 +715,82 @@ void Chttp2ServerListener::ActiveConnection::OnDrainGraceTimeExpiry() { grpc_error_handle Chttp2ServerListener::Create( Server* server, grpc_resolved_address* addr, const ChannelArgs& args, Chttp2ServerArgsModifier args_modifier, int* port_num) { - Chttp2ServerListener* listener = nullptr; - // The bulk of this method is inside of a lambda to make cleanup - // easier without using goto. - grpc_error_handle error = [&]() { - grpc_error_handle error; - // Create Chttp2ServerListener. - listener = new Chttp2ServerListener(server, args, args_modifier); - error = grpc_tcp_server_create( - &listener->tcp_server_shutdown_complete_, - grpc_event_engine::experimental::ChannelArgsEndpointConfig(args), - OnAccept, listener, &listener->tcp_server_); + // Create Chttp2ServerListener. + OrphanablePtr listener = + MakeOrphanable(server, args, args_modifier, + server->config_fetcher()); + // The tcp_server will be unreffed when the listener is orphaned, which could + // be at the end of this function if the listener was not added to the + // server's set of listeners. + grpc_error_handle error = grpc_tcp_server_create( + &listener->tcp_server_shutdown_complete_, ChannelArgsEndpointConfig(args), + OnAccept, listener.get(), &listener->tcp_server_); + if (!error.ok()) return error; + if (listener->config_fetcher_ != nullptr) { + listener->resolved_address_ = *addr; + // TODO(yashykt): Consider binding so as to be able to return the port + // number. + } else { + error = grpc_tcp_server_add_port(listener->tcp_server_, addr, port_num); if (!error.ok()) return error; - if (server->config_fetcher() != nullptr) { - listener->resolved_address_ = *addr; - // TODO(yashykt): Consider binding so as to be able to return the port - // number. - } else { - error = grpc_tcp_server_add_port(listener->tcp_server_, addr, port_num); - if (!error.ok()) return error; - } - // Create channelz node. - if (args.GetBool(GRPC_ARG_ENABLE_CHANNELZ) - .value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) { - auto string_address = grpc_sockaddr_to_uri(addr); - if (!string_address.ok()) { - return GRPC_ERROR_CREATE(string_address.status().ToString()); - } - listener->channelz_listen_socket_ = - MakeRefCounted( - *string_address, - absl::StrCat("chttp2 listener ", *string_address)); - } - // Register with the server only upon success - server->AddListener(OrphanablePtr(listener)); - return absl::OkStatus(); - }(); - if (!error.ok()) { - if (listener != nullptr) { - if (listener->tcp_server_ != nullptr) { - // listener is deleted when tcp_server_ is shutdown. - grpc_tcp_server_unref(listener->tcp_server_); - } else { - delete listener; - } + } + // Create channelz node. + if (args.GetBool(GRPC_ARG_ENABLE_CHANNELZ) + .value_or(GRPC_ENABLE_CHANNELZ_DEFAULT)) { + auto string_address = grpc_sockaddr_to_uri(addr); + if (!string_address.ok()) { + return GRPC_ERROR_CREATE(string_address.status().ToString()); } + listener->channelz_listen_socket_ = + MakeRefCounted( + *string_address, absl::StrCat("chttp2 listener ", *string_address)); } - return error; + // Register with the server only upon success + server->AddListener(std::move(listener)); + return absl::OkStatus(); } grpc_error_handle Chttp2ServerListener::CreateWithAcceptor( Server* server, const char* name, const ChannelArgs& args, Chttp2ServerArgsModifier args_modifier) { - Chttp2ServerListener* listener = - new Chttp2ServerListener(server, args, args_modifier); + auto listener = MakeOrphanable( + server, args, args_modifier, server->config_fetcher()); grpc_error_handle error = grpc_tcp_server_create( - &listener->tcp_server_shutdown_complete_, - grpc_event_engine::experimental::ChannelArgsEndpointConfig(args), - OnAccept, listener, &listener->tcp_server_); - if (!error.ok()) { - delete listener; - return error; - } + &listener->tcp_server_shutdown_complete_, ChannelArgsEndpointConfig(args), + OnAccept, listener.get(), &listener->tcp_server_); + if (!error.ok()) return error; // TODO(yangg) channelz TcpServerFdHandler** arg_val = args.GetPointer(name); *arg_val = grpc_tcp_server_create_fd_handler(listener->tcp_server_); - server->AddListener(OrphanablePtr(listener)); + server->AddListener(std::move(listener)); return absl::OkStatus(); } +Chttp2ServerListener* Chttp2ServerListener::CreateForPassiveListener( + Server* server, const ChannelArgs& args, + std::shared_ptr passive_listener) { + // TODO(hork): figure out how to handle channelz in this case + auto listener = MakeOrphanable( + server, args, /*args_modifier=*/ + [](const ChannelArgs& args, grpc_error_handle*) { return args; }, nullptr, + std::move(passive_listener)); + auto listener_ptr = listener.get(); + server->AddListener(std::move(listener)); + return listener_ptr; +} + Chttp2ServerListener::Chttp2ServerListener( Server* server, const ChannelArgs& args, - Chttp2ServerArgsModifier args_modifier) + Chttp2ServerArgsModifier args_modifier, + grpc_server_config_fetcher* config_fetcher, + std::shared_ptr passive_listener) : server_(server), args_modifier_(args_modifier), args_(args), memory_quota_(args.GetObject()->memory_quota()), - connection_quota_(MakeRefCounted()) { + connection_quota_(MakeRefCounted()), + config_fetcher_(config_fetcher), + passive_listener_(std::move(passive_listener)) { auto max_allowed_incoming_connections = args.GetInt(GRPC_ARG_MAX_ALLOWED_INCOMING_CONNECTIONS); if (max_allowed_incoming_connections.has_value()) { @@ -800,6 +805,9 @@ Chttp2ServerListener::~Chttp2ServerListener() { // Flush queued work before destroying handshaker factory, since that // may do a synchronous unref. ExecCtx::Get()->Flush(); + if (passive_listener_ != nullptr) { + passive_listener_->ListenerDestroyed(); + } if (on_destroy_done_ != nullptr) { ExecCtx::Run(DEBUG_LOCATION, on_destroy_done_, absl::OkStatus()); ExecCtx::Get()->Flush(); @@ -809,10 +817,11 @@ Chttp2ServerListener::~Chttp2ServerListener() { // Server callback: start listening on our ports void Chttp2ServerListener::Start( Server* /*server*/, const std::vector* /* pollsets */) { - if (server_->config_fetcher() != nullptr) { - auto watcher = std::make_unique(Ref()); + if (config_fetcher_ != nullptr) { + auto watcher = std::make_unique( + RefAsSubclass()); config_fetcher_watcher_ = watcher.get(); - server_->config_fetcher()->StartWatch( + config_fetcher_->StartWatch( grpc_sockaddr_to_string(&resolved_address_, false).value(), std::move(watcher)); } else { @@ -826,7 +835,9 @@ void Chttp2ServerListener::Start( } void Chttp2ServerListener::StartListening() { - grpc_tcp_server_start(tcp_server_, &server_->pollsets()); + if (tcp_server_ != nullptr) { + grpc_tcp_server_start(tcp_server_, &server_->pollsets()); + } } void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) { @@ -834,6 +845,12 @@ void Chttp2ServerListener::SetOnDestroyDone(grpc_closure* on_destroy_done) { on_destroy_done_ = on_destroy_done; } +void Chttp2ServerListener::AcceptConnectedEndpoint( + std::unique_ptr endpoint) { + OnAccept(this, grpc_event_engine_endpoint_create(std::move(endpoint)), + /*accepting_pollset=*/nullptr, /*acceptor=*/nullptr); +} + void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, grpc_pollset* accepting_pollset, grpc_tcp_server_acceptor* acceptor) { @@ -858,7 +875,7 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, endpoint_cleanup(error); return; } - if (self->server_->config_fetcher() != nullptr) { + if (self->config_fetcher_ != nullptr) { if (connection_manager == nullptr) { grpc_error_handle error = GRPC_ERROR_CREATE( "No ConnectionManager configured. Closing connection."); @@ -899,7 +916,7 @@ void Chttp2ServerListener::OnAccept(void* arg, grpc_endpoint* tcp, // heap-use-after-free issues where `Ref()` is invoked when the ref of // tcp_server_ has already reached 0. (Ref() implementation of // Chttp2ServerListener is grpc_tcp_server_ref().) - listener_ref = self->Ref(); + listener_ref = self->RefAsSubclass(); self->connections_.emplace(connection.get(), std::move(connection)); } } @@ -914,7 +931,7 @@ void Chttp2ServerListener::TcpServerShutdownComplete( void* arg, grpc_error_handle /*error*/) { Chttp2ServerListener* self = static_cast(arg); self->channelz_listen_socket_.reset(); - delete self; + self->Unref(); } // Server callback: destroy the tcp listener (so we don't generate further @@ -923,7 +940,8 @@ void Chttp2ServerListener::Orphan() { // Cancel the watch before shutting down so as to avoid holding a ref to the // listener in the watcher. if (config_fetcher_watcher_ != nullptr) { - server_->config_fetcher()->CancelWatch(config_fetcher_watcher_); + CHECK_NE(config_fetcher_, nullptr); + config_fetcher_->CancelWatch(config_fetcher_watcher_); } std::map> connections; grpc_tcp_server* tcp_server; @@ -941,12 +959,14 @@ void Chttp2ServerListener::Orphan() { } tcp_server = tcp_server_; } - grpc_tcp_server_shutdown_listeners(tcp_server); - grpc_tcp_server_unref(tcp_server); + if (tcp_server != nullptr) { + grpc_tcp_server_shutdown_listeners(tcp_server); + grpc_tcp_server_unref(tcp_server); + } else { + Unref(); + } } -} // namespace - // // Chttp2ServerAddPort() // @@ -1047,6 +1067,50 @@ ChannelArgs ModifyArgsForConnection(const ChannelArgs& args, } } // namespace + +namespace experimental { + +absl::Status PassiveListenerImpl::AcceptConnectedEndpoint( + std::unique_ptr endpoint) { + CHECK_NE(server_.get(), nullptr); + RefCountedPtr listener; + { + MutexLock lock(&mu_); + if (listener_ != nullptr) { + listener = + listener_->RefIfNonZero().TakeAsSubclass(); + } + } + if (listener == nullptr) { + return absl::UnavailableError("passive listener already shut down"); + } + ExecCtx exec_ctx; + listener->AcceptConnectedEndpoint(std::move(endpoint)); + return absl::OkStatus(); +} + +absl::Status PassiveListenerImpl::AcceptConnectedFd(int fd) { + CHECK_NE(server_.get(), nullptr); + ExecCtx exec_ctx; + auto& args = server_->channel_args(); + auto* supports_fd = QueryExtension( + /*engine=*/args.GetObjectRef().get()); + if (supports_fd == nullptr) { + return absl::UnimplementedError( + "The server's EventEngine does not support adding endpoints from " + "connected file descriptors."); + } + auto endpoint = + supports_fd->CreateEndpointFromFd(fd, ChannelArgsEndpointConfig(args)); + return AcceptConnectedEndpoint(std::move(endpoint)); +} + +void PassiveListenerImpl::ListenerDestroyed() { + MutexLock lock(&mu_); + listener_ = nullptr; +} + +} // namespace experimental } // namespace grpc_core int grpc_server_add_http2_port(grpc_server* server, const char* addr, @@ -1144,3 +1208,31 @@ void grpc_server_add_channel_from_fd(grpc_server* /* server */, int /* fd */, } #endif // GPR_SUPPORT_CHANNELS_FROM_FD + +absl::Status grpc_server_add_passive_listener( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener) { + grpc_core::ExecCtx exec_ctx; + GRPC_API_TRACE("grpc_server_add_passive_listener(server=%p, credentials=%p)", + 2, (server, credentials)); + // Create security context. + if (credentials == nullptr) { + return absl::UnavailableError( + "No credentials specified for passive listener"); + } + auto sc = credentials->create_security_connector(grpc_core::ChannelArgs()); + if (sc == nullptr) { + return absl::UnavailableError( + absl::StrCat("Unable to create secure server with credentials of type ", + credentials->type().name())); + } + auto args = server->channel_args() + .SetObject(credentials->Ref()) + .SetObject(std::move(sc)); + passive_listener->listener_ = + grpc_core::Chttp2ServerListener::CreateForPassiveListener( + server, args, passive_listener); + passive_listener->server_ = server->Ref(); + return absl::OkStatus(); +} diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.h b/src/core/ext/transport/chttp2/server/chttp2_server.h index 26c178be917..25d38236aed 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.h +++ b/src/core/ext/transport/chttp2/server/chttp2_server.h @@ -21,6 +21,7 @@ #include +#include #include #include "src/core/lib/channel/channel_args.h" @@ -42,6 +43,38 @@ grpc_error_handle Chttp2ServerAddPort( Server* server, const char* addr, const ChannelArgs& args, Chttp2ServerArgsModifier connection_args_modifier, int* port_num); +class Chttp2ServerListener; +namespace experimental { + +// An implementation of the public C++ passive listener interface. +// The server builder holds a weak_ptr to one of these objects, and the +// application owns the instance. +class PassiveListenerImpl final : public PassiveListener { + public: + absl::Status AcceptConnectedEndpoint( + std::unique_ptr + endpoint) override ABSL_LOCKS_EXCLUDED(mu_); + + absl::Status AcceptConnectedFd(GRPC_UNUSED int fd) override + ABSL_LOCKS_EXCLUDED(mu_); + + void ListenerDestroyed() ABSL_LOCKS_EXCLUDED(mu_); + + private: + // note: the grpc_core::Server redundant namespace qualification is + // required for older gcc versions. + friend absl::Status(::grpc_server_add_passive_listener)( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener); + + Mutex mu_; + // Data members will be populated when initialized. + RefCountedPtr server_; + Chttp2ServerListener* listener_; +}; + +} // namespace experimental } // namespace grpc_core #endif // GRPC_SRC_CORE_EXT_TRANSPORT_CHTTP2_SERVER_CHTTP2_SERVER_H diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 9a28649dd52..4acd9b51b3f 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -35,6 +35,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/hash/hash.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/meta/type_traits.h" #include "absl/random/random.h" #include "absl/status/status.h" @@ -1324,7 +1325,7 @@ static bool contains_non_ok_status(grpc_metadata_batch* batch) { static void log_metadata(const grpc_metadata_batch* md_batch, uint32_t id, bool is_client, bool is_initial) { - gpr_log(GPR_INFO, "--metadata--"); + LOG(INFO) << "--metadata--"; const std::string prefix = absl::StrCat( "HTTP:", id, is_initial ? ":HDR" : ":TRL", is_client ? ":CLI:" : ":SVR:"); md_batch->Log([&prefix](absl::string_view key, absl::string_view value) { diff --git a/src/core/ext/transport/cronet/BUILD b/src/core/ext/transport/cronet/BUILD index 50897682381..1e7e8253e62 100644 --- a/src/core/ext/transport/cronet/BUILD +++ b/src/core/ext/transport/cronet/BUILD @@ -41,6 +41,7 @@ grpc_cc_library( ], external_deps = [ "absl/log:check", + "absl/log:log", "cronet_c_for_grpc", ], language = "c++", diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc index 7dd316bfca8..dbbd3e63123 100644 --- a/src/core/ext/transport/inproc/inproc_transport.cc +++ b/src/core/ext/transport/inproc/inproc_transport.cc @@ -28,6 +28,7 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/promise/promise.h" #include "src/core/lib/promise/try_seq.h" +#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/surface/channel_create.h" #include "src/core/lib/transport/transport.h" #include "src/core/server/server.h" @@ -39,8 +40,18 @@ class InprocClientTransport; class InprocServerTransport final : public ServerTransport { public: - void SetAcceptor(Acceptor* acceptor) override { - acceptor_ = acceptor; + explicit InprocServerTransport(const ChannelArgs& args) + : event_engine_( + args.GetObjectRef()), + call_arena_allocator_(MakeRefCounted( + args.GetObject() + ->memory_quota() + ->CreateMemoryAllocator("inproc_server"), + 1024)) {} + + void SetCallDestination( + RefCountedPtr unstarted_call_handler) override { + unstarted_call_handler_ = unstarted_call_handler; ConnectionState expect = ConnectionState::kInitial; state_.compare_exchange_strong(expect, ConnectionState::kReady, std::memory_order_acq_rel, @@ -95,7 +106,11 @@ class InprocServerTransport final : public ServerTransport { case ConnectionState::kReady: break; } - return acceptor_->CreateCall(std::move(md), acceptor_->CreateArena()); + auto* arena = call_arena_allocator_->MakeArena(); + auto server_call = MakeCallPair(std::move(md), event_engine_.get(), arena, + call_arena_allocator_, nullptr); + unstarted_call_handler_->StartCall(std::move(server_call.handler)); + return std::move(server_call.initiator); } OrphanablePtr MakeClientTransport(); @@ -105,11 +120,14 @@ class InprocServerTransport final : public ServerTransport { std::atomic state_{ConnectionState::kInitial}; std::atomic disconnecting_{false}; - Acceptor* acceptor_; + RefCountedPtr unstarted_call_handler_; absl::Status disconnect_error_; Mutex state_tracker_mu_; ConnectivityStateTracker state_tracker_ ABSL_GUARDED_BY(state_tracker_mu_){ "inproc_server_transport", GRPC_CHANNEL_CONNECTING}; + const std::shared_ptr + event_engine_; + const RefCountedPtr call_arena_allocator_; }; class InprocClientTransport final : public ClientTransport { @@ -118,16 +136,19 @@ class InprocClientTransport final : public ClientTransport { RefCountedPtr server_transport) : server_transport_(std::move(server_transport)) {} - void StartCall(CallHandler call_handler) override { - call_handler.SpawnGuarded( + void StartCall(CallHandler child_call_handler) override { + child_call_handler.SpawnGuarded( "pull_initial_metadata", - TrySeq(call_handler.PullClientInitialMetadata(), + TrySeq(child_call_handler.PullClientInitialMetadata(), [server_transport = server_transport_, - call_handler](ClientMetadataHandle md) { - auto call_initiator = + child_call_handler](ClientMetadataHandle md) { + auto server_call_initiator = server_transport->AcceptCall(std::move(md)); - if (!call_initiator.ok()) return call_initiator.status(); - ForwardCall(call_handler, std::move(*call_initiator)); + if (!server_call_initiator.ok()) { + return server_call_initiator.status(); + } + ForwardCall(child_call_handler, + std::move(*server_call_initiator)); return absl::OkStatus(); })); } @@ -155,7 +176,6 @@ class InprocClientTransport final : public ClientTransport { bool UsePromiseBasedTransport() { if (!IsPromiseBasedInprocTransportEnabled()) return false; CHECK(IsPromiseBasedClientCallEnabled()); - CHECK(IsPromiseBasedServerCallEnabled()); return true; } @@ -180,7 +200,7 @@ OrphanablePtr MakeLameChannel(absl::string_view why, OrphanablePtr MakeInprocChannel(Server* server, ChannelArgs client_channel_args) { - auto transports = MakeInProcessTransportPair(); + auto transports = MakeInProcessTransportPair(server->channel_args()); auto client_transport = std::move(transports.first); auto server_transport = std::move(transports.second); auto error = @@ -205,8 +225,9 @@ OrphanablePtr MakeInprocChannel(Server* server, } // namespace std::pair, OrphanablePtr> -MakeInProcessTransportPair() { - auto server_transport = MakeOrphanable(); +MakeInProcessTransportPair(const ChannelArgs& server_channel_args) { + auto server_transport = + MakeOrphanable(server_channel_args); auto client_transport = server_transport->MakeClientTransport(); return std::make_pair(std::move(client_transport), std::move(server_transport)); diff --git a/src/core/ext/transport/inproc/inproc_transport.h b/src/core/ext/transport/inproc/inproc_transport.h index 676b5f1fa32..46dc9b540f1 100644 --- a/src/core/ext/transport/inproc/inproc_transport.h +++ b/src/core/ext/transport/inproc/inproc_transport.h @@ -30,7 +30,7 @@ extern grpc_core::TraceFlag grpc_inproc_trace; namespace grpc_core { std::pair, OrphanablePtr> -MakeInProcessTransportPair(); +MakeInProcessTransportPair(const ChannelArgs& server_channel_args); } diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc index 9b28a321db1..c428bac0006 100644 --- a/src/core/lib/channel/channel_stack.cc +++ b/src/core/lib/channel/channel_stack.cc @@ -305,13 +305,6 @@ grpc_core::NextPromiseFactory ClientNext(grpc_channel_element* elem) { }; } -grpc_core::NextPromiseFactory ServerNext(grpc_channel_element* elem) { - return [elem](grpc_core::CallArgs args) { - return elem->filter->make_call_promise(elem, std::move(args), - ServerNext(elem - 1)); - }; -} - } // namespace grpc_core::ArenaPromise @@ -319,12 +312,6 @@ grpc_channel_stack::MakeClientCallPromise(grpc_core::CallArgs call_args) { return ClientNext(grpc_channel_stack_element(this, 0))(std::move(call_args)); } -grpc_core::ArenaPromise -grpc_channel_stack::MakeServerCallPromise(grpc_core::CallArgs call_args) { - return ServerNext(grpc_channel_stack_element(this, this->count - 1))( - std::move(call_args)); -} - void grpc_channel_stack::InitClientCallSpine( grpc_core::CallSpineInterface* call) { for (size_t i = 0; i < count; i++) { @@ -338,19 +325,6 @@ void grpc_channel_stack::InitClientCallSpine( } } -void grpc_channel_stack::InitServerCallSpine( - grpc_core::CallSpineInterface* call) { - for (size_t i = 0; i < count; i++) { - auto* elem = grpc_channel_stack_element(this, count - 1 - i); - if (elem->filter->init_call == nullptr) { - grpc_core::Crash( - absl::StrCat("Filter '", elem->filter->name, - "' does not support the call-v3 interface")); - } - elem->filter->init_call(elem, call); - } -} - void grpc_call_log_op(const char* file, int line, gpr_log_severity severity, grpc_call_element* elem, grpc_transport_stream_op_batch* op) { diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index affd34a4191..030173fcd31 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -241,7 +241,6 @@ struct grpc_channel_stack { MakeServerCallPromise(grpc_core::CallArgs call_args); void InitClientCallSpine(grpc_core::CallSpineInterface* call); - void InitServerCallSpine(grpc_core::CallSpineInterface* call); }; // A call stack tracks a set of related filters for one call, and guarantees diff --git a/src/core/lib/channel/metrics.cc b/src/core/lib/channel/metrics.cc index d662f3275ad..c3b734fc44d 100644 --- a/src/core/lib/channel/metrics.cc +++ b/src/core/lib/channel/metrics.cc @@ -34,12 +34,14 @@ GlobalInstrumentsRegistry::GetInstrumentList() { return *instruments; } -GlobalInstrumentsRegistry::GlobalUInt64CounterHandle -GlobalInstrumentsRegistry::RegisterUInt64Counter( +GlobalInstrumentsRegistry::InstrumentID +GlobalInstrumentsRegistry::RegisterInstrument( + GlobalInstrumentsRegistry::ValueType value_type, + GlobalInstrumentsRegistry::InstrumentType instrument_type, absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { + absl::string_view unit, bool enable_by_default, + absl::Span label_keys, + absl::Span optional_label_keys) { auto& instruments = GetInstrumentList(); for (const auto& descriptor : instruments) { if (descriptor.name == name) { @@ -47,11 +49,11 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter( absl::StrFormat("Metric name %s has already been registered.", name)); } } - uint32_t index = instruments.size(); + InstrumentID index = instruments.size(); CHECK_LT(index, std::numeric_limits::max()); GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kUInt64; - descriptor.instrument_type = InstrumentType::kCounter; + descriptor.value_type = value_type; + descriptor.instrument_type = instrument_type; descriptor.index = index; descriptor.enable_by_default = enable_by_default; descriptor.name = name; @@ -61,169 +63,7 @@ GlobalInstrumentsRegistry::RegisterUInt64Counter( descriptor.optional_label_keys = {optional_label_keys.begin(), optional_label_keys.end()}; instruments.push_back(std::move(descriptor)); - GlobalUInt64CounterHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalDoubleCounterHandle -GlobalInstrumentsRegistry::RegisterDoubleCounter( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kDouble; - descriptor.instrument_type = InstrumentType::kCounter; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalDoubleCounterHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle -GlobalInstrumentsRegistry::RegisterUInt64Histogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kUInt64; - descriptor.instrument_type = InstrumentType::kHistogram; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalUInt64HistogramHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle -GlobalInstrumentsRegistry::RegisterDoubleHistogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kDouble; - descriptor.instrument_type = InstrumentType::kHistogram; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalDoubleHistogramHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle -GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kInt64; - descriptor.instrument_type = InstrumentType::kCallbackGauge; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalCallbackInt64GaugeHandle handle; - handle.index = index; - return handle; -} - -GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle -GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default) { - auto& instruments = GetInstrumentList(); - for (const auto& descriptor : instruments) { - if (descriptor.name == name) { - Crash( - absl::StrFormat("Metric name %s has already been registered.", name)); - } - } - uint32_t index = instruments.size(); - CHECK_LT(index, std::numeric_limits::max()); - GlobalInstrumentDescriptor descriptor; - descriptor.value_type = ValueType::kDouble; - descriptor.instrument_type = InstrumentType::kCallbackGauge; - descriptor.index = index; - descriptor.enable_by_default = enable_by_default; - descriptor.name = name; - descriptor.description = description; - descriptor.unit = unit; - descriptor.label_keys = {label_keys.begin(), label_keys.end()}; - descriptor.optional_label_keys = {optional_label_keys.begin(), - optional_label_keys.end()}; - instruments.push_back(std::move(descriptor)); - GlobalCallbackDoubleGaugeHandle handle; - handle.index = index; - return handle; + return index; } void GlobalInstrumentsRegistry::ForEach( @@ -242,7 +82,7 @@ GlobalInstrumentsRegistry::GetInstrumentDescriptor( RegisteredMetricCallback::RegisteredMetricCallback( GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group, absl::AnyInvocable callback, - std::vector metrics, + std::vector metrics, Duration min_interval) : stats_plugin_group_(stats_plugin_group), callback_(std::move(callback)), @@ -259,15 +99,6 @@ RegisteredMetricCallback::~RegisteredMetricCallback() { } } -std::unique_ptr -GlobalStatsPluginRegistry::StatsPluginGroup::RegisterCallback( - absl::AnyInvocable callback, - std::vector metrics, - Duration min_interval) { - return std::make_unique( - *this, std::move(callback), std::move(metrics), min_interval); -} - void GlobalStatsPluginRegistry::StatsPluginGroup::AddClientCallTracers( const Slice& path, bool registered_method, grpc_call_context_element* call_context) { diff --git a/src/core/lib/channel/metrics.h b/src/core/lib/channel/metrics.h index 7c161c80829..797be93fd7d 100644 --- a/src/core/lib/channel/metrics.h +++ b/src/core/lib/channel/metrics.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "absl/functional/any_invocable.h" @@ -45,6 +46,27 @@ constexpr absl::string_view kMetricLabelTarget = "grpc.target"; // startup, before the execution of the main function (during dynamic // initialization time). Using this API after the main function begins may // result into missing instruments. This API is thread-unsafe. +// +// The registration of instruments is done through the templated +// RegistrationBuilder API and gets back a handle with an opaque type. At +// runtime, the handle should be used with the StatsPluginGroup API to record +// metrics for the instruments. +// +// At dynamic initialization time: +// const auto kMetricHandle = +// GlobalInstrumentsRegistry::RegisterUInt64Counter( +// "name", +// "description", +// "unit", /*enable_by_default=*/false) +// .Labels(kLabel1, kLabel2, kLabel3) +// .OptionalLabels(kOptionalLabel1, kOptionalLabel2) +// .Build(); +// +// At runtime time: +// stats_plugin_group.AddCounter(kMetricHandle, 1, +// {"label_value_1", "label_value_2", "label_value_3"}, +// {"optional_label_value_1", "optional_label_value_2"}); +// class GlobalInstrumentsRegistry { public: enum class ValueType { @@ -78,46 +100,113 @@ class GlobalInstrumentsRegistry { // runs or between different versions. InstrumentID index; }; - struct GlobalUInt64CounterHandle : public GlobalInstrumentHandle {}; - struct GlobalDoubleCounterHandle : public GlobalInstrumentHandle {}; - struct GlobalUInt64HistogramHandle : public GlobalInstrumentHandle {}; - struct GlobalDoubleHistogramHandle : public GlobalInstrumentHandle {}; - struct GlobalCallbackInt64GaugeHandle : public GlobalInstrumentHandle {}; - struct GlobalCallbackDoubleGaugeHandle : public GlobalInstrumentHandle {}; - using GlobalCallbackHandle = absl::variant; + + template + struct TypedGlobalInstrumentHandle : public GlobalInstrumentHandle {}; + + template + class RegistrationBuilder { + public: + template + RegistrationBuilder Labels(Args&&... args) { + return RegistrationBuilder( + name_, description_, unit_, enable_by_default_, + std::array({args...}), + optional_label_keys_); + } + + template + RegistrationBuilder OptionalLabels( + Args&&... args) { + return RegistrationBuilder( + name_, description_, unit_, enable_by_default_, label_keys_, + std::array({args...})); + } + + TypedGlobalInstrumentHandle Build() { + TypedGlobalInstrumentHandle handle; + handle.index = RegisterInstrument(V, I, name_, description_, unit_, + enable_by_default_, label_keys_, + optional_label_keys_); + return handle; + } + + private: + friend class GlobalInstrumentsRegistry; + + RegistrationBuilder(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) + : name_(name), + description_(description), + unit_(unit), + enable_by_default_(enable_by_default) {} + + RegistrationBuilder(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default, + std::array label_keys, + std::array optional_label_keys) + : name_(name), + description_(description), + unit_(unit), + enable_by_default_(enable_by_default), + label_keys_(std::move(label_keys)), + optional_label_keys_(std::move(optional_label_keys)) {} + + absl::string_view name_; + absl::string_view description_; + absl::string_view unit_; + bool enable_by_default_; + std::array label_keys_; + std::array optional_label_keys_; + }; // Creates instrument in the GlobalInstrumentsRegistry. - static GlobalUInt64CounterHandle RegisterUInt64Counter( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalDoubleCounterHandle RegisterDoubleCounter( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalUInt64HistogramHandle RegisterUInt64Histogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalDoubleHistogramHandle RegisterDoubleHistogram( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalCallbackInt64GaugeHandle RegisterCallbackInt64Gauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); - static GlobalCallbackDoubleGaugeHandle RegisterCallbackDoubleGauge( - absl::string_view name, absl::string_view description, - absl::string_view unit, absl::Span label_keys, - absl::Span optional_label_keys, - bool enable_by_default); + static RegistrationBuilder + RegisterUInt64Counter(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, enable_by_default); + } + static RegistrationBuilder + RegisterDoubleCounter(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, enable_by_default); + } + static RegistrationBuilder + RegisterUInt64Histogram(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, + enable_by_default); + } + static RegistrationBuilder + RegisterDoubleHistogram(absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder(name, description, unit, + enable_by_default); + } + static RegistrationBuilder + RegisterCallbackInt64Gauge(absl::string_view name, + absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder( + name, description, unit, enable_by_default); + } + static RegistrationBuilder + RegisterCallbackDoubleGauge(absl::string_view name, + absl::string_view description, + absl::string_view unit, bool enable_by_default) { + return RegistrationBuilder( + name, description, unit, enable_by_default); + } static void ForEach( absl::FunctionRef f); @@ -131,6 +220,12 @@ class GlobalInstrumentsRegistry { static std::vector& GetInstrumentList(); + static InstrumentID RegisterInstrument( + ValueType value_type, InstrumentType instrument_type, + absl::string_view name, absl::string_view description, + absl::string_view unit, bool enable_by_default, + absl::Span label_keys, + absl::Span optional_label_keys); }; // An interface for implementing callback-style metrics. @@ -139,13 +234,35 @@ class CallbackMetricReporter { public: virtual ~CallbackMetricReporter() = default; - virtual void Report( - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, - int64_t value, absl::Span label_values, + template + void Report( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kInt64, + GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N> + handle, + int64_t value, std::array label_values, + std::array optional_values) { + ReportInt64(handle, value, label_values, optional_values); + } + template + void Report( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, M, N> + handle, + double value, std::array label_values, + std::array optional_values) { + ReportDouble(handle, value, label_values, optional_values); + } + + private: + virtual void ReportInt64( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, + absl::Span label_values, absl::Span optional_values) = 0; - virtual void Report( - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle, - double value, absl::Span label_values, + virtual void ReportDouble( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_values) = 0; }; @@ -179,15 +296,15 @@ class StatsPlugin { // this measurement and must match with their corresponding keys in // GlobalInstrumentsRegistry::RegisterUInt64Counter(). virtual void AddCounter( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_label_values) = 0; // Adds \a value to the double counter specified by \a handle. \a label_values // and \a optional_label_values specify attributes that are associated with // this measurement and must match with their corresponding keys in // GlobalInstrumentsRegistry::RegisterDoubleCounter(). virtual void AddCounter( - GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_label_values) = 0; // Records a uint64 \a value to the histogram specified by \a handle. \a @@ -195,16 +312,16 @@ class StatsPlugin { // associated with this measurement and must match with their corresponding // keys in GlobalInstrumentsRegistry::RegisterUInt64Histogram(). virtual void RecordHistogram( - GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_label_values) = 0; // Records a double \a value to the histogram specified by \a handle. \a // label_values and \a optional_label_values specify attributes that are // associated with this measurement and must match with their corresponding // keys in GlobalInstrumentsRegistry::RegisterDoubleHistogram(). virtual void RecordHistogram( - GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, - double value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_label_values) = 0; // Adds a callback to be invoked when the stats plugin wants to // populate the corresponding metrics (see callback->metrics() for list). @@ -255,20 +372,53 @@ class GlobalStatsPluginRegistry { } // Adds a counter in all stats plugins within the group. See the StatsPlugin // interface for more documentation and valid types. - template - void AddCounter(HandleType handle, ValueType value, - absl::Span label_values, - absl::Span optional_values) { + template + void AddCounter( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N> + handle, + uint64_t value, std::array label_values, + std::array optional_values) { + for (auto& state : plugins_state_) { + state.plugin->AddCounter(handle, value, label_values, optional_values); + } + } + template + void AddCounter( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kCounter, M, N> + handle, + double value, std::array label_values, + std::array optional_values) { for (auto& state : plugins_state_) { state.plugin->AddCounter(handle, value, label_values, optional_values); } } // Records a value to a histogram in all stats plugins within the group. See // the StatsPlugin interface for more documentation and valid types. - template - void RecordHistogram(HandleType handle, ValueType value, - absl::Span label_values, - absl::Span optional_values) { + template + void RecordHistogram( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N> + handle, + uint64_t value, std::array label_values, + std::array optional_values) { + for (auto& state : plugins_state_) { + state.plugin->RecordHistogram(handle, value, label_values, + optional_values); + } + } + template + void RecordHistogram( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle< + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kHistogram, M, N> + handle, + double value, std::array label_values, + std::array optional_values) { for (auto& state : plugins_state_) { state.plugin->RecordHistogram(handle, value, label_values, optional_values); @@ -285,11 +435,17 @@ class GlobalStatsPluginRegistry { // the lifetime of the callback; when the returned object is // destroyed, the callback is de-registered. The returned object // must not outlive the StatsPluginGroup object that created it. + template GRPC_MUST_USE_RESULT std::unique_ptr - RegisterCallback( - absl::AnyInvocable callback, - std::vector metrics, - Duration min_interval = Duration::Seconds(5)); + RegisterCallback(absl::AnyInvocable callback, + Duration min_interval, Args... args) { + AssertIsCallbackGaugeHandle(args...); + return std::make_unique( + *this, std::move(callback), + std::vector{ + args...}, + min_interval); + } // Adds all available client call tracers associated with the stats plugins // within the group to \a call_context. @@ -307,6 +463,24 @@ class GlobalStatsPluginRegistry { std::shared_ptr plugin; }; + // C++17 has fold expression that may simplify this. + template + static constexpr void AssertIsCallbackGaugeHandle( + GlobalInstrumentsRegistry::TypedGlobalInstrumentHandle) { + static_assert(V == GlobalInstrumentsRegistry::ValueType::kInt64 || + V == GlobalInstrumentsRegistry::ValueType::kDouble, + "ValueType must be kInt64 or kDouble"); + static_assert( + I == GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge, + "InstrumentType must be kCallbackGauge"); + } + template + static constexpr void AssertIsCallbackGaugeHandle(T t, Args&&... args) { + AssertIsCallbackGaugeHandle(t); + AssertIsCallbackGaugeHandle(args...); + } + std::vector plugins_state_; }; @@ -335,7 +509,7 @@ class RegisteredMetricCallback { RegisteredMetricCallback( GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group, absl::AnyInvocable callback, - std::vector metrics, + std::vector metrics, Duration min_interval); ~RegisteredMetricCallback(); @@ -344,8 +518,8 @@ class RegisteredMetricCallback { void Run(CallbackMetricReporter& reporter) { callback_(reporter); } // Returns the set of metrics that this callback will modify. - const std::vector& metrics() - const { + const std::vector& + metrics() const { return metrics_; } @@ -356,7 +530,7 @@ class RegisteredMetricCallback { private: GlobalStatsPluginRegistry::StatsPluginGroup& stats_plugin_group_; absl::AnyInvocable callback_; - std::vector metrics_; + std::vector metrics_; Duration min_interval_; }; diff --git a/src/core/lib/event_engine/extensions/supports_fd.h b/src/core/lib/event_engine/extensions/supports_fd.h index 66ea1c2b345..30f0d2ad0e6 100644 --- a/src/core/lib/event_engine/extensions/supports_fd.h +++ b/src/core/lib/event_engine/extensions/supports_fd.h @@ -112,6 +112,13 @@ class EventEngineSupportsFdExtension { int fd, const EndpointConfig& config, MemoryAllocator memory_allocator) = 0; + /// Creates an EventEngine::Endpoint from an fd which is already assumed to be + /// connected to a remote peer. See \a CreatePosixEndpointFromFd for details. + /// This has the same behavior, but the \a memory_allocator is taken from the + /// EndpointConfig's resource quota. + virtual std::unique_ptr CreateEndpointFromFd( + int fd, const EndpointConfig& config) = 0; + /// Called when the posix listener has accepted a new client connection. /// \a listener_fd - The listening socket fd that accepted the new client /// connection. diff --git a/src/core/lib/event_engine/posix_engine/posix_engine.cc b/src/core/lib/event_engine/posix_engine/posix_engine.cc index e96c969617c..e4d5deb73dc 100644 --- a/src/core/lib/event_engine/posix_engine/posix_engine.cc +++ b/src/core/lib/event_engine/posix_engine/posix_engine.cc @@ -677,6 +677,22 @@ PosixEventEngine::CreatePosixEndpointFromFd(int fd, #endif // GRPC_PLATFORM_SUPPORTS_POSIX_POLLING } +std::unique_ptr PosixEventEngine::CreateEndpointFromFd( + int fd, const EndpointConfig& config) { + auto options = TcpOptionsFromEndpointConfig(config); + MemoryAllocator allocator; + if (options.memory_allocator_factory != nullptr) { + return CreatePosixEndpointFromFd( + fd, config, + options.memory_allocator_factory->CreateMemoryAllocator( + absl::StrCat("allocator:", fd))); + } + return CreatePosixEndpointFromFd( + fd, config, + options.resource_quota->memory_quota()->CreateMemoryAllocator( + absl::StrCat("allocator:", fd))); +} + absl::StatusOr> PosixEventEngine::CreateListener( Listener::AcceptCallback on_accept, diff --git a/src/core/lib/event_engine/posix_engine/posix_engine.h b/src/core/lib/event_engine/posix_engine/posix_engine.h index 257cd6b34b5..ea426c379c9 100644 --- a/src/core/lib/event_engine/posix_engine/posix_engine.h +++ b/src/core/lib/event_engine/posix_engine/posix_engine.h @@ -172,6 +172,8 @@ class PosixEventEngine final : public PosixEventEngineWithFdSupport, std::unique_ptr CreatePosixEndpointFromFd( int fd, const EndpointConfig& config, MemoryAllocator memory_allocator) override; + std::unique_ptr CreateEndpointFromFd( + int fd, const EndpointConfig& config) override; absl::StatusOr> CreateListener( Listener::AcceptCallback on_accept, diff --git a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc index a923b293a9e..eeaed8abb3c 100644 --- a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +++ b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc @@ -227,18 +227,19 @@ void WorkStealingThreadPool::PostforkChild() { pool_->Postfork(); } WorkStealingThreadPool::WorkStealingThreadPoolImpl::WorkStealingThreadPoolImpl( size_t reserve_threads) - : reserve_threads_(reserve_threads), queue_(this), lifeguard_(this) {} + : reserve_threads_(reserve_threads), queue_(this) {} void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Start() { for (size_t i = 0; i < reserve_threads_; i++) { StartThread(); } - lifeguard_.Start(); + grpc_core::MutexLock lock(&lifeguard_ptr_mu_); + lifeguard_ = std::make_unique(this); } void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Run( EventEngine::Closure* closure) { - DCHECK(quiesced_.load(std::memory_order_relaxed) == false); + CHECK(!IsQuiesced()); if (g_local_queue != nullptr && g_local_queue->owner() == this) { g_local_queue->Add(closure); } else { @@ -283,7 +284,8 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Quiesce() { } CHECK(queue_.Empty()); quiesced_.store(true, std::memory_order_relaxed); - lifeguard_.BlockUntilShutdownAndReset(); + grpc_core::MutexLock lock(&lifeguard_ptr_mu_); + lifeguard_.reset(); } bool WorkStealingThreadPool::WorkStealingThreadPoolImpl::SetThrottled( @@ -325,7 +327,8 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::PrepareFork() { if (!threads_were_shut_down.ok() && g_log_verbose_failures) { DumpStacksAndCrash(); } - lifeguard_.BlockUntilShutdownAndReset(); + grpc_core::MutexLock lock(&lifeguard_ptr_mu_); + lifeguard_.reset(); } void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Postfork() { @@ -374,9 +377,7 @@ WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::Lifeguard( .set_max_backoff(kLifeguardMaxSleepBetweenChecks) .set_multiplier(1.3)), lifeguard_should_shut_down_(std::make_unique()), - lifeguard_is_shut_down_(std::make_unique()) {} - -void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::Start() { + lifeguard_is_shut_down_(std::make_unique()) { // lifeguard_running_ is set early to avoid a quiesce race while the // lifeguard is still starting up. lifeguard_running_.store(true); @@ -411,8 +412,7 @@ void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard:: lifeguard_is_shut_down_->Notify(); } -void WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard:: - BlockUntilShutdownAndReset() { +WorkStealingThreadPool::WorkStealingThreadPoolImpl::Lifeguard::~Lifeguard() { lifeguard_should_shut_down_->Notify(); while (lifeguard_running_.load(std::memory_order_relaxed)) { GRPC_LOG_EVERY_N_SEC_DELAYED(kBlockingQuiesceLogRateSeconds, GPR_DEBUG, diff --git a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h index 3dcc55aab6c..7543db92900 100644 --- a/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h +++ b/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.h @@ -155,11 +155,7 @@ class WorkStealingThreadPool final : public ThreadPool { class Lifeguard { public: explicit Lifeguard(WorkStealingThreadPoolImpl* pool); - // Start the lifeguard thread. - void Start(); - // Block until the lifeguard thread is shut down. - // Afterwards, reset the lifeguard state so it can start again cleanly. - void BlockUntilShutdownAndReset(); + ~Lifeguard(); private: // The main body of the lifeguard thread. @@ -194,7 +190,8 @@ class WorkStealingThreadPool final : public ThreadPool { // at a time. std::atomic throttled_{false}; WorkSignal work_signal_; - Lifeguard lifeguard_; + grpc_core::Mutex lifeguard_ptr_mu_; + std::unique_ptr lifeguard_ ABSL_GUARDED_BY(lifeguard_ptr_mu_); // Set of threads for verbose failure debugging grpc_core::Mutex thd_set_mu_; absl::flat_hash_set thds_ ABSL_GUARDED_BY(thd_set_mu_); diff --git a/src/core/lib/experiments/experiments.cc b/src/core/lib/experiments/experiments.cc index 3f9e6a840ca..4bf01759fc2 100644 --- a/src/core/lib/experiments/experiments.cc +++ b/src/core/lib/experiments/experiments.cc @@ -88,23 +88,17 @@ const char* const additional_constraints_promise_based_client_call = "{}"; const uint8_t required_experiments_promise_based_client_call[] = { static_cast(grpc_core::kExperimentIdEventEngineClient), static_cast(grpc_core::kExperimentIdEventEngineListener)}; -const char* const description_promise_based_server_call = - "If set, use the new gRPC promise based call code when it's appropriate " - "(ie when all filters in a stack are promise based)"; -const char* const additional_constraints_promise_based_server_call = "{}"; const char* const description_chaotic_good = "If set, enable the chaotic good load transport (this is mostly here for " "testing)"; const char* const additional_constraints_chaotic_good = "{}"; const uint8_t required_experiments_chaotic_good[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_promise_based_inproc_transport = "Use promises for the in-process transport."; const char* const additional_constraints_promise_based_inproc_transport = "{}"; const uint8_t required_experiments_promise_based_inproc_transport[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_rstpit = "On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short " "duration"; @@ -184,15 +178,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"promise_based_client_call", description_promise_based_client_call, additional_constraints_promise_based_client_call, required_experiments_promise_based_client_call, 2, false, true}, - {"promise_based_server_call", description_promise_based_server_call, - additional_constraints_promise_based_server_call, nullptr, 0, false, true}, {"chaotic_good", description_chaotic_good, - additional_constraints_chaotic_good, required_experiments_chaotic_good, 2, + additional_constraints_chaotic_good, required_experiments_chaotic_good, 1, false, true}, {"promise_based_inproc_transport", description_promise_based_inproc_transport, additional_constraints_promise_based_inproc_transport, - required_experiments_promise_based_inproc_transport, 2, false, false}, + required_experiments_promise_based_inproc_transport, 1, false, false}, {"rstpit", description_rstpit, additional_constraints_rstpit, nullptr, 0, false, true}, {"schedule_cancellation_over_write", @@ -288,23 +280,17 @@ const char* const additional_constraints_promise_based_client_call = "{}"; const uint8_t required_experiments_promise_based_client_call[] = { static_cast(grpc_core::kExperimentIdEventEngineClient), static_cast(grpc_core::kExperimentIdEventEngineListener)}; -const char* const description_promise_based_server_call = - "If set, use the new gRPC promise based call code when it's appropriate " - "(ie when all filters in a stack are promise based)"; -const char* const additional_constraints_promise_based_server_call = "{}"; const char* const description_chaotic_good = "If set, enable the chaotic good load transport (this is mostly here for " "testing)"; const char* const additional_constraints_chaotic_good = "{}"; const uint8_t required_experiments_chaotic_good[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_promise_based_inproc_transport = "Use promises for the in-process transport."; const char* const additional_constraints_promise_based_inproc_transport = "{}"; const uint8_t required_experiments_promise_based_inproc_transport[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_rstpit = "On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short " "duration"; @@ -358,7 +344,7 @@ const ExperimentMetadata g_experiment_metadata[] = { {"client_privacy", description_client_privacy, additional_constraints_client_privacy, nullptr, 0, false, false}, {"event_engine_client", description_event_engine_client, - additional_constraints_event_engine_client, nullptr, 0, false, true}, + additional_constraints_event_engine_client, nullptr, 0, true, true}, {"event_engine_dns", description_event_engine_dns, additional_constraints_event_engine_dns, nullptr, 0, false, false}, {"event_engine_listener", description_event_engine_listener, @@ -384,15 +370,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"promise_based_client_call", description_promise_based_client_call, additional_constraints_promise_based_client_call, required_experiments_promise_based_client_call, 2, false, true}, - {"promise_based_server_call", description_promise_based_server_call, - additional_constraints_promise_based_server_call, nullptr, 0, false, true}, {"chaotic_good", description_chaotic_good, - additional_constraints_chaotic_good, required_experiments_chaotic_good, 2, + additional_constraints_chaotic_good, required_experiments_chaotic_good, 1, false, true}, {"promise_based_inproc_transport", description_promise_based_inproc_transport, additional_constraints_promise_based_inproc_transport, - required_experiments_promise_based_inproc_transport, 2, false, false}, + required_experiments_promise_based_inproc_transport, 1, false, false}, {"rstpit", description_rstpit, additional_constraints_rstpit, nullptr, 0, false, true}, {"schedule_cancellation_over_write", @@ -488,23 +472,17 @@ const char* const additional_constraints_promise_based_client_call = "{}"; const uint8_t required_experiments_promise_based_client_call[] = { static_cast(grpc_core::kExperimentIdEventEngineClient), static_cast(grpc_core::kExperimentIdEventEngineListener)}; -const char* const description_promise_based_server_call = - "If set, use the new gRPC promise based call code when it's appropriate " - "(ie when all filters in a stack are promise based)"; -const char* const additional_constraints_promise_based_server_call = "{}"; const char* const description_chaotic_good = "If set, enable the chaotic good load transport (this is mostly here for " "testing)"; const char* const additional_constraints_chaotic_good = "{}"; const uint8_t required_experiments_chaotic_good[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_promise_based_inproc_transport = "Use promises for the in-process transport."; const char* const additional_constraints_promise_based_inproc_transport = "{}"; const uint8_t required_experiments_promise_based_inproc_transport[] = { - static_cast(grpc_core::kExperimentIdPromiseBasedClientCall), - static_cast(grpc_core::kExperimentIdPromiseBasedServerCall)}; + static_cast(grpc_core::kExperimentIdPromiseBasedClientCall)}; const char* const description_rstpit = "On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short " "duration"; @@ -584,15 +562,13 @@ const ExperimentMetadata g_experiment_metadata[] = { {"promise_based_client_call", description_promise_based_client_call, additional_constraints_promise_based_client_call, required_experiments_promise_based_client_call, 2, false, true}, - {"promise_based_server_call", description_promise_based_server_call, - additional_constraints_promise_based_server_call, nullptr, 0, false, true}, {"chaotic_good", description_chaotic_good, - additional_constraints_chaotic_good, required_experiments_chaotic_good, 2, + additional_constraints_chaotic_good, required_experiments_chaotic_good, 1, false, true}, {"promise_based_inproc_transport", description_promise_based_inproc_transport, additional_constraints_promise_based_inproc_transport, - required_experiments_promise_based_inproc_transport, 2, false, false}, + required_experiments_promise_based_inproc_transport, 1, false, false}, {"rstpit", description_rstpit, additional_constraints_rstpit, nullptr, 0, false, true}, {"schedule_cancellation_over_write", diff --git a/src/core/lib/experiments/experiments.h b/src/core/lib/experiments/experiments.h index faf13fca4cf..16220be2591 100644 --- a/src/core/lib/experiments/experiments.h +++ b/src/core/lib/experiments/experiments.h @@ -79,7 +79,6 @@ inline bool IsPendingQueueCapEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_PICK_FIRST_NEW inline bool IsPickFirstNewEnabled() { return true; } inline bool IsPromiseBasedClientCallEnabled() { return false; } -inline bool IsPromiseBasedServerCallEnabled() { return false; } inline bool IsChaoticGoodEnabled() { return false; } inline bool IsPromiseBasedInprocTransportEnabled() { return false; } inline bool IsRstpitEnabled() { return false; } @@ -100,7 +99,8 @@ inline bool IsCallStatusOverrideOnCancellationEnabled() { return true; } inline bool IsCallV3Enabled() { return false; } inline bool IsCanaryClientPrivacyEnabled() { return false; } inline bool IsClientPrivacyEnabled() { return false; } -inline bool IsEventEngineClientEnabled() { return false; } +#define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_CLIENT +inline bool IsEventEngineClientEnabled() { return true; } inline bool IsEventEngineDnsEnabled() { return false; } #define GRPC_EXPERIMENT_IS_INCLUDED_EVENT_ENGINE_LISTENER inline bool IsEventEngineListenerEnabled() { return true; } @@ -118,7 +118,6 @@ inline bool IsPendingQueueCapEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_PICK_FIRST_NEW inline bool IsPickFirstNewEnabled() { return true; } inline bool IsPromiseBasedClientCallEnabled() { return false; } -inline bool IsPromiseBasedServerCallEnabled() { return false; } inline bool IsChaoticGoodEnabled() { return false; } inline bool IsPromiseBasedInprocTransportEnabled() { return false; } inline bool IsRstpitEnabled() { return false; } @@ -158,7 +157,6 @@ inline bool IsPendingQueueCapEnabled() { return true; } #define GRPC_EXPERIMENT_IS_INCLUDED_PICK_FIRST_NEW inline bool IsPickFirstNewEnabled() { return true; } inline bool IsPromiseBasedClientCallEnabled() { return false; } -inline bool IsPromiseBasedServerCallEnabled() { return false; } inline bool IsChaoticGoodEnabled() { return false; } inline bool IsPromiseBasedInprocTransportEnabled() { return false; } inline bool IsRstpitEnabled() { return false; } @@ -194,7 +192,6 @@ enum ExperimentIds { kExperimentIdPendingQueueCap, kExperimentIdPickFirstNew, kExperimentIdPromiseBasedClientCall, - kExperimentIdPromiseBasedServerCall, kExperimentIdChaoticGood, kExperimentIdPromiseBasedInprocTransport, kExperimentIdRstpit, @@ -276,10 +273,6 @@ inline bool IsPickFirstNewEnabled() { inline bool IsPromiseBasedClientCallEnabled() { return IsExperimentEnabled(kExperimentIdPromiseBasedClientCall); } -#define GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL -inline bool IsPromiseBasedServerCallEnabled() { - return IsExperimentEnabled(kExperimentIdPromiseBasedServerCall); -} #define GRPC_EXPERIMENT_IS_INCLUDED_CHAOTIC_GOOD inline bool IsChaoticGoodEnabled() { return IsExperimentEnabled(kExperimentIdChaoticGood); diff --git a/src/core/lib/experiments/experiments.yaml b/src/core/lib/experiments/experiments.yaml index 0712c8afd85..0e00f5c4d68 100644 --- a/src/core/lib/experiments/experiments.yaml +++ b/src/core/lib/experiments/experiments.yaml @@ -64,7 +64,7 @@ If set, enable the chaotic good load transport (this is mostly here for testing) expiry: 2024/09/09 owner: ctiller@google.com - requires: [promise_based_client_call, promise_based_server_call] + requires: [promise_based_client_call] test_tags: [core_end2end_test] - name: client_privacy description: @@ -170,14 +170,7 @@ owner: ctiller@google.com test_tags: [] allow_in_fuzzing_config: false # experiment currently crashes if enabled - requires: [promise_based_client_call, promise_based_server_call] -- name: promise_based_server_call - description: - If set, use the new gRPC promise based call code when it's appropriate - (ie when all filters in a stack are promise based) - expiry: 2024/06/14 - owner: ctiller@google.com - test_tags: ["core_end2end_test", "logging_test"] + requires: [promise_based_client_call] - name: rstpit description: On RST_STREAM on a server, reduce MAX_CONCURRENT_STREAMS for a short duration diff --git a/src/core/lib/experiments/rollouts.yaml b/src/core/lib/experiments/rollouts.yaml index 6f4e84827f0..97018a672cd 100644 --- a/src/core/lib/experiments/rollouts.yaml +++ b/src/core/lib/experiments/rollouts.yaml @@ -58,9 +58,7 @@ # not tested on iOS at all ios: broken posix: false - # TODO(hork): resolve when the client end2end test flake rate reduces to - # a tolerable amount. - windows: false + windows: true - name: event_engine_dns default: # not tested on iOS at all @@ -96,8 +94,6 @@ ios: broken windows: broken posix: false -- name: promise_based_server_call - default: false - name: rstpit default: false - name: schedule_cancellation_over_write diff --git a/src/core/lib/gpr/android/log.cc b/src/core/lib/gpr/android/log.cc index 34c705b8764..c368f3aa324 100644 --- a/src/core/lib/gpr/android/log.cc +++ b/src/core/lib/gpr/android/log.cc @@ -57,23 +57,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, free(message); } -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char* output = NULL; - - final_slash = strrchr(args->file, '/'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - asprintf(&output, "%s:%d] %s", display_file, args->line, args->message); - - __android_log_write(severity_to_log_priority(args->severity), "GRPC", output); - - // allocated by asprintf => use free, not gpr_free - free(output); -} - #endif // GPR_ANDROID diff --git a/src/core/lib/gpr/linux/log.cc b/src/core/lib/gpr/linux/log.cc index a24e28fa82c..f09ecb2dbbc 100644 --- a/src/core/lib/gpr/linux/log.cc +++ b/src/core/lib/gpr/linux/log.cc @@ -47,10 +47,6 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/examine_stack.h" -int gpr_should_log_stacktrace(gpr_log_severity severity); - -static long sys_gettid(void) { return syscall(__NR_gettid); } - void gpr_log(const char* file, int line, gpr_log_severity severity, const char* format, ...) { // Avoid message construction if gpr_log_message won't log @@ -70,45 +66,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, free(message); } -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - static thread_local long tid(0); - if (tid == 0) tid = sys_gettid(); - - timer = static_cast(now.tv_sec); - final_slash = strrchr(args->file, '/'); - if (final_slash == nullptr) { - display_file = args->file; - } else { - display_file = final_slash + 1; - } - - if (!localtime_r(&timer, &tm)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - std::string prefix = absl::StrFormat( - "%s%s.%09" PRId32 " %7ld %s:%d]", gpr_log_severity_string(args->severity), - time_buffer, now.tv_nsec, tid, display_file, args->line); - - absl::optional stack_trace = - gpr_should_log_stacktrace(args->severity) - ? grpc_core::GetCurrentStackTrace() - : absl::nullopt; - if (stack_trace) { - fprintf(stderr, "%-70s %s\n%s\n", prefix.c_str(), args->message, - stack_trace->c_str()); - } else { - fprintf(stderr, "%-70s %s\n", prefix.c_str(), args->message); - } -} - #endif // GPR_LINUX_LOG diff --git a/src/core/lib/gpr/log.cc b/src/core/lib/gpr/log.cc index 1755d99122d..f1cd2938137 100644 --- a/src/core/lib/gpr/log.cc +++ b/src/core/lib/gpr/log.cc @@ -77,10 +77,6 @@ int gpr_should_log(gpr_log_severity severity) { } void gpr_default_log(gpr_log_func_args* args) { - if (!grpc_core::ConfigVars::Get().AbslLogging()) { - gpr_platform_log(args); - return; - } switch (args->severity) { case GPR_LOG_SEVERITY_DEBUG: // Log DEBUG messages as VLOG(2). @@ -99,13 +95,6 @@ void gpr_default_log(gpr_log_func_args* args) { } } -int gpr_should_log_stacktrace(gpr_log_severity severity) { - return static_cast(severity) >= - gpr_atm_no_barrier_load(&g_min_severity_to_print_stacktrace) - ? 1 - : 0; -} - void gpr_log_message(const char* file, int line, gpr_log_severity severity, const char* message) { if (gpr_should_log(severity) == 0) { diff --git a/src/core/lib/gpr/posix/log.cc b/src/core/lib/gpr/posix/log.cc index 4e933b7c4be..09791014ef8 100644 --- a/src/core/lib/gpr/posix/log.cc +++ b/src/core/lib/gpr/posix/log.cc @@ -38,10 +38,6 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/examine_stack.h" -int gpr_should_log_stacktrace(gpr_log_severity severity); - -static intptr_t sys_gettid(void) { return (intptr_t)pthread_self(); } - void gpr_log(const char* file, int line, gpr_log_severity severity, const char* format, ...) { // Avoid message construction if gpr_log_message won't log @@ -70,42 +66,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, gpr_free(allocated); } -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - - timer = (time_t)now.tv_sec; - final_slash = strrchr(args->file, '/'); - if (final_slash == nullptr) - display_file = args->file; - else - display_file = final_slash + 1; - - if (!localtime_r(&timer, &tm)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - std::string prefix = absl::StrFormat( - "%s%s.%09d %7" PRIdPTR " %s:%d]", gpr_log_severity_string(args->severity), - time_buffer, (int)(now.tv_nsec), sys_gettid(), display_file, args->line); - - absl::optional stack_trace = - gpr_should_log_stacktrace(args->severity) - ? grpc_core::GetCurrentStackTrace() - : absl::nullopt; - if (stack_trace) { - fprintf(stderr, "%-70s %s\n%s\n", prefix.c_str(), args->message, - stack_trace->c_str()); - } else { - fprintf(stderr, "%-70s %s\n", prefix.c_str(), args->message); - } -} - #endif // defined(GPR_POSIX_LOG) diff --git a/src/core/lib/gpr/windows/log.cc b/src/core/lib/gpr/windows/log.cc index 4dc48698140..e4f2d14f008 100644 --- a/src/core/lib/gpr/windows/log.cc +++ b/src/core/lib/gpr/windows/log.cc @@ -33,8 +33,6 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/examine_stack.h" -int gpr_should_log_stacktrace(gpr_log_severity severity); - void gpr_log(const char* file, int line, gpr_log_severity severity, const char* format, ...) { // Avoid message construction if gpr_log_message won't log @@ -72,45 +70,4 @@ void gpr_log(const char* file, int line, gpr_log_severity severity, gpr_free(message); } -// Simple starter implementation -void gpr_platform_log(gpr_log_func_args* args) { - const char* final_slash; - const char* display_file; - char time_buffer[64]; - time_t timer; - gpr_timespec now = gpr_now(GPR_CLOCK_REALTIME); - struct tm tm; - - timer = (time_t)now.tv_sec; - final_slash = strrchr(args->file, '\\'); - if (final_slash == NULL) - display_file = args->file; - else - display_file = final_slash + 1; - - if (localtime_s(&tm, &timer)) { - strcpy(time_buffer, "error:localtime"); - } else if (0 == - strftime(time_buffer, sizeof(time_buffer), "%m%d %H:%M:%S", &tm)) { - strcpy(time_buffer, "error:strftime"); - } - - absl::optional stack_trace = - gpr_should_log_stacktrace(args->severity) - ? grpc_core::GetCurrentStackTrace() - : absl::nullopt; - if (stack_trace) { - fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n%s\n", - gpr_log_severity_string(args->severity), time_buffer, - (int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line, - args->message, stack_trace->c_str()); - } else { - fprintf(stderr, "%s%s.%09u %5lu %s:%d] %s\n", - gpr_log_severity_string(args->severity), time_buffer, - (int)(now.tv_nsec), GetCurrentThreadId(), display_file, args->line, - args->message); - } - fflush(stderr); -} - #endif // GPR_WINDOWS_LOG diff --git a/src/core/lib/gprpp/dump_args.cc b/src/core/lib/gprpp/dump_args.cc new file mode 100644 index 00000000000..e5bc183246b --- /dev/null +++ b/src/core/lib/gprpp/dump_args.cc @@ -0,0 +1,54 @@ +// Copyright 2024 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 "src/core/lib/gprpp/dump_args.h" + +#include "absl/log/check.h" +#include "absl/strings/ascii.h" +#include "absl/strings/string_view.h" + +namespace grpc_core { +namespace dump_args_detail { + +std::ostream& operator<<(std::ostream& out, const DumpArgs& args) { + // Parse the argument string into a vector of keys. + // #__VA_ARGS__ produces a stringified version of the arguments passed to the + // macro. It's comma separated, and we can use that to split the string into + // keys. Those keys might include parenthesis for e.g. argument lists, and so + // we need to skip commas that are inside parenthesis. + std::vector keys; + int depth = 0; + const char* start = args.arg_string_; + for (const char* p = args.arg_string_; *p; ++p) { + if (*p == '(') { + ++depth; + } else if (*p == ')') { + --depth; + } else if (*p == ',' && depth == 0) { + keys.push_back(absl::string_view(start, p - start)); + start = p + 1; + } + } + keys.push_back(start); + CHECK_EQ(keys.size(), args.arg_dumpers_.size()); + for (size_t i = 0; i < keys.size(); i++) { + if (i != 0) out << ", "; + out << absl::StripAsciiWhitespace(keys[i]) << " = "; + args.arg_dumpers_[i](out); + } + return out; +} + +} // namespace dump_args_detail +} // namespace grpc_core \ No newline at end of file diff --git a/src/core/lib/gprpp/dump_args.h b/src/core/lib/gprpp/dump_args.h new file mode 100644 index 00000000000..c2b66ce2be3 --- /dev/null +++ b/src/core/lib/gprpp/dump_args.h @@ -0,0 +1,69 @@ +// Copyright 2024 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_SRC_CORE_LIB_GPRPP_DUMP_ARGS_H +#define GRPC_SRC_CORE_LIB_GPRPP_DUMP_ARGS_H + +#include +#include + +#include "absl/functional/any_invocable.h" + +namespace grpc_core { +namespace dump_args_detail { + +// Helper function... just ignore the initializer list passed into it. +// Allows doing 'statements' via parameter pack expansion in C++11 - given +// template : +// do_these_things({foo()...}); +// will execute foo() for each T in Ts. +template +void do_these_things(std::initializer_list) {} + +class DumpArgs { + public: + template + explicit DumpArgs(const char* arg_string, const Args&... args) + : arg_string_(arg_string) { + do_these_things( + {AddDumper([a = &args](std::ostream& os) { os << *a; })...}); + } + + friend std::ostream& operator<<(std::ostream& out, const DumpArgs& args); + + private: + int AddDumper(absl::AnyInvocable dumper) { + arg_dumpers_.push_back(std::move(dumper)); + return 0; + } + + const char* arg_string_; + std::vector> arg_dumpers_; +}; + +} // namespace dump_args_detail +} // namespace grpc_core + +// Helper to print a list of variables and their values. +// Each type must be streamable to std::ostream. +// Usage: +// int a = 1; +// int b = 2; +// LOG(INFO) << GRPC_DUMP_ARGS(a, b) +// Output: +// a = 1, b = 2 +#define GRPC_DUMP_ARGS(...) \ + grpc_core::dump_args_detail::DumpArgs(#__VA_ARGS__, __VA_ARGS__) + +#endif // GRPC_SRC_CORE_LIB_GPRPP_DUMP_ARGS_H diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index c36f3833d9f..6461b10a6cb 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -41,6 +41,7 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" @@ -100,14 +101,14 @@ static int epoll_create_and_cloexec() { #ifdef GRPC_LINUX_EPOLL_CREATE1 int fd = epoll_create1(EPOLL_CLOEXEC); if (fd < 0) { - gpr_log(GPR_ERROR, "epoll_create1 unavailable"); + LOG(ERROR) << "epoll_create1 unavailable"; } #else int fd = epoll_create(MAX_EPOLL_EVENTS); if (fd < 0) { - gpr_log(GPR_ERROR, "epoll_create unavailable"); + LOG(ERROR) << "epoll_create unavailable"; } else if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { - gpr_log(GPR_ERROR, "fcntl following epoll_create failed"); + LOG(ERROR) << "fcntl following epoll_create failed"; return -1; } #endif @@ -891,7 +892,7 @@ static bool check_neighborhood_for_available_poller( } } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. beaten to choose next poller"); + LOG(INFO) << " .. beaten to choose next poller"; } } // even if we didn't win the cas, there's a worker, we can stop @@ -990,7 +991,7 @@ static void end_worker(grpc_pollset* pollset, grpc_pollset_worker* worker, gpr_cv_destroy(&worker->cv); } if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. remove worker"); + LOG(INFO) << " .. remove worker"; } if (EMPTIED == worker_remove(pollset, worker)) { pollset_maybe_finish_shutdown(pollset); @@ -1081,7 +1082,7 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, if (root_worker == nullptr) { pollset->kicked_without_poller = true; if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kicked_without_poller"); + LOG(INFO) << " .. kicked_without_poller"; } goto done; } @@ -1146,7 +1147,7 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, } } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kicked while waking up"); + LOG(INFO) << " .. kicked while waking up"; } goto done; } @@ -1156,7 +1157,7 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, if (specific_worker->state == KICKED) { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. specific worker already kicked"); + LOG(INFO) << " .. specific worker already kicked"; } goto done; } else if (g_current_thread_worker == specific_worker) { @@ -1169,21 +1170,21 @@ static grpc_error_handle pollset_kick(grpc_pollset* pollset, reinterpret_cast( gpr_atm_no_barrier_load(&g_active_poller))) { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kick active poller"); + LOG(INFO) << " .. kick active poller"; } SET_KICK_STATE(specific_worker, KICKED); ret_err = grpc_wakeup_fd_wakeup(&global_wakeup_fd); goto done; } else if (specific_worker->initialized_cv) { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kick waiting worker"); + LOG(INFO) << " .. kick waiting worker"; } SET_KICK_STATE(specific_worker, KICKED); gpr_cv_signal(&specific_worker->cv); goto done; } else { if (GRPC_TRACE_FLAG_ENABLED(grpc_polling_trace)) { - gpr_log(GPR_INFO, " .. kick non-waiting worker"); + LOG(INFO) << " .. kick non-waiting worker"; } SET_KICK_STATE(specific_worker, KICKED); goto done; @@ -1311,7 +1312,7 @@ static void reset_event_manager_on_fork() { static bool init_epoll1_linux() { if (!g_is_shutdown) return true; if (!grpc_has_wakeup_fd()) { - gpr_log(GPR_ERROR, "Skipping epoll1 because of no wakeup fd."); + LOG(ERROR) << "Skipping epoll1 because of no wakeup fd."; return false; } diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc index 880b10c1764..46c54c9502e 100644 --- a/src/core/lib/iomgr/tcp_posix.cc +++ b/src/core/lib/iomgr/tcp_posix.cc @@ -46,6 +46,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -212,7 +213,7 @@ class TcpZerocopySendCtx { if (send_records_ == nullptr || free_send_records_ == nullptr) { gpr_free(send_records_); gpr_free(free_send_records_); - gpr_log(GPR_INFO, "Disabling TCP TX zerocopy due to memory pressure.\n"); + LOG(INFO) << "Disabling TCP TX zerocopy due to memory pressure.\n"; memory_limited_ = true; } else { for (int idx = 0; idx < max_sends_; ++idx) { @@ -836,7 +837,7 @@ static void tcp_destroy(grpc_endpoint* ep) { static void perform_reclamation(grpc_tcp* tcp) ABSL_LOCKS_EXCLUDED(tcp->read_mu) { if (GRPC_TRACE_FLAG_ENABLED(grpc_resource_quota_trace)) { - gpr_log(GPR_INFO, "TCP: benign reclamation to free memory"); + LOG(INFO) << "TCP: benign reclamation to free memory"; } tcp->read_mu.Lock(); if (tcp->incoming_buffer != nullptr) { @@ -1294,7 +1295,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg, if (setsockopt(tcp->fd, SOL_SOCKET, SO_TIMESTAMPING, static_cast(&opt), sizeof(opt)) != 0) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Failed to set timestamping options on the socket."); + LOG(ERROR) << "Failed to set timestamping options on the socket."; } return false; } @@ -1380,7 +1381,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, cmsghdr* opt_stats = nullptr; if (next_cmsg == nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Received timestamp without extended error"); + LOG(ERROR) << "Received timestamp without extended error"; } return cmsg; } @@ -1392,7 +1393,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, next_cmsg = CMSG_NXTHDR(msg, opt_stats); if (next_cmsg == nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Received timestamp without extended error"); + LOG(ERROR) << "Received timestamp without extended error"; } return opt_stats; } @@ -1402,7 +1403,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, !(next_cmsg->cmsg_type == IP_RECVERR || next_cmsg->cmsg_type == IPV6_RECVERR)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_ERROR, "Unexpected control message"); + LOG(ERROR) << "Unexpected control message"; } return cmsg; } @@ -1412,7 +1413,7 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg, auto serr = reinterpret_cast(CMSG_DATA(next_cmsg)); if (serr->ee_errno != ENOMSG || serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) { - gpr_log(GPR_ERROR, "Unexpected control message"); + LOG(ERROR) << "Unexpected control message"; return cmsg; } tcp->tb_list.ProcessTimestamp(serr, opt_stats, tss); @@ -1462,7 +1463,7 @@ static bool process_errors(grpc_tcp* tcp) { return processed_err; } if (GPR_UNLIKELY((msg.msg_flags & MSG_CTRUNC) != 0)) { - gpr_log(GPR_ERROR, "Error message was truncated."); + LOG(ERROR) << "Error message was truncated."; } if (msg.msg_controllen == 0) { @@ -1539,14 +1540,14 @@ static bool tcp_write_with_timestamps(grpc_tcp* /*tcp*/, struct msghdr* /*msg*/, ssize_t* /*sent_length*/, int* /* saved_errno */, int /*additional_flags*/) { - gpr_log(GPR_ERROR, "Write with timestamps not supported for this platform"); + LOG(ERROR) << "Write with timestamps not supported for this platform"; CHECK(0); return false; } static void tcp_handle_error(void* /*arg*/ /* grpc_tcp */, grpc_error_handle /*error*/) { - gpr_log(GPR_ERROR, "Error handling is not supported for this platform"); + LOG(ERROR) << "Error handling is not supported for this platform"; CHECK(0); } #endif // GRPC_LINUX_ERRQUEUE @@ -1842,7 +1843,7 @@ static void tcp_handle_write(void* arg /* grpc_tcp */, : tcp_flush(tcp, &error); if (!flush_result) { if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "write: delayed"); + LOG(INFO) << "write: delayed"; } notify_on_write(tcp); // tcp_flush does not populate error if it has returned false. @@ -1915,7 +1916,7 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf, tcp->write_cb = cb; tcp->current_zerocopy_send = zerocopy_send_record; if (GRPC_TRACE_FLAG_ENABLED(grpc_tcp_trace)) { - gpr_log(GPR_INFO, "write: delayed"); + LOG(INFO) << "write: delayed"; } notify_on_write(tcp); } else { @@ -2029,7 +2030,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd, if (err == 0) { tcp->tcp_zerocopy_send_ctx.set_enabled(true); } else { - gpr_log(GPR_ERROR, "Failed to set zerocopy options on the socket."); + LOG(ERROR) << "Failed to set zerocopy options on the socket."; } #endif } diff --git a/src/core/lib/promise/detail/promise_like.h b/src/core/lib/promise/detail/promise_like.h index a8b80172c22..8e73577675a 100644 --- a/src/core/lib/promise/detail/promise_like.h +++ b/src/core/lib/promise/detail/promise_like.h @@ -17,6 +17,7 @@ #include +#include "absl/functional/any_invocable.h" #include "absl/meta/type_traits.h" #include @@ -63,6 +64,10 @@ auto WrapInPoll(T&& x) -> decltype(PollWrapper::Wrap(std::forward(x))) { return PollWrapper::Wrap(std::forward(x)); } +// T -> T, const T& -> T +template +using RemoveCVRef = absl::remove_cv_t>; + template class PromiseLike; @@ -73,7 +78,7 @@ template class PromiseLike::type>::value>> { private: - GPR_NO_UNIQUE_ADDRESS F f_; + GPR_NO_UNIQUE_ADDRESS RemoveCVRef f_; public: // NOLINTNEXTLINE - internal detail that drastically simplifies calling code. @@ -82,10 +87,6 @@ class PromiseLike::Type; }; -// T -> T, const T& -> T -template -using RemoveCVRef = absl::remove_cv_t>; - } // namespace promise_detail } // namespace grpc_core diff --git a/src/core/lib/promise/detail/seq_state.h b/src/core/lib/promise/detail/seq_state.h index 3e69e60b741..841cd6cb042 100644 --- a/src/core/lib/promise/detail/seq_state.h +++ b/src/core/lib/promise/detail/seq_state.h @@ -23,6 +23,7 @@ #include "absl/base/attributes.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include @@ -144,22 +145,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/2", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/2"; } auto result = prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/2 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/2 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -177,14 +177,14 @@ struct SeqState { default: case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/2", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/2"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/2 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/2 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -287,22 +287,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/3", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/3"; } auto result = prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/3 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/3 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -319,22 +318,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/3", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/3"; } auto result = prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/3 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/3 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -352,14 +350,14 @@ struct SeqState { default: case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/3", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/3"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/3 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/3 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -489,22 +487,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/4"; } auto result = prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/4 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/4 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -521,22 +518,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/4"; } auto result = prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/4 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/4 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -553,22 +549,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/4"; } auto result = prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/4 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/4 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -586,14 +581,14 @@ struct SeqState { default: case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/4", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/4"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/4 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/4 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -751,22 +746,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/5"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/5 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -783,22 +777,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/5"; } auto result = prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/5 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -815,22 +808,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/5"; } auto result = prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/5 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -847,22 +839,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/5"; } auto result = prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/5 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/5 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -880,14 +871,14 @@ struct SeqState { default: case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/5", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/5"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/5 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/5 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -1082,22 +1073,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/6"; } auto result = prior.prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/6 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -1115,22 +1105,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/6"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/6 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -1147,22 +1136,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/6"; } auto result = prior.prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/6 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -1179,22 +1167,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/6"; } auto result = prior.prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/6 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -1211,22 +1198,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/6", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/6"; } auto result = prior.current_promise(); PromiseResult4* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/6 gets %s", this, - p != nullptr - ? (PromiseResultTraits4::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits4::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/6 gets " + << (p != nullptr + ? (PromiseResultTraits4::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits4::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits4::IsOk(*p)) { @@ -1249,9 +1235,9 @@ struct SeqState { } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 6/6 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 6/6 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -1478,22 +1464,21 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/7"; } auto result = prior.prior.prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/7 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -1511,22 +1496,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/7"; } auto result = prior.prior.prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/7 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -1544,22 +1528,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/7"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/7 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -1576,22 +1559,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/7"; } auto result = prior.prior.prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/7 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -1608,22 +1590,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/7"; } auto result = prior.prior.current_promise(); PromiseResult4* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits4::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits4::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/7 gets " + << (p != nullptr + ? (PromiseResultTraits4::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits4::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits4::IsOk(*p)) { @@ -1640,22 +1621,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState5: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 6/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 6/7"; } auto result = prior.current_promise(); PromiseResult5* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 6/7 gets %s", this, - p != nullptr - ? (PromiseResultTraits5::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits5::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 6/7 gets " + << (p != nullptr + ? (PromiseResultTraits5::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits5::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits5::IsOk(*p)) { @@ -1673,14 +1653,14 @@ struct SeqState { default: case State::kState6: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 7/7", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 7/7"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 7/7 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 7/7 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; @@ -1940,23 +1920,22 @@ struct SeqState { switch (state) { case State::kState0: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 1/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 1/8"; } auto result = prior.prior.prior.prior.prior.prior.prior.current_promise(); PromiseResult0* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 1/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits0::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits0::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 1/8 gets " + << (p != nullptr + ? (PromiseResultTraits0::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits0::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits0::IsOk(*p)) { @@ -1975,22 +1954,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState1: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 2/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 2/8"; } auto result = prior.prior.prior.prior.prior.prior.current_promise(); PromiseResult1* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 2/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits1::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits1::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 2/8 gets " + << (p != nullptr + ? (PromiseResultTraits1::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits1::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits1::IsOk(*p)) { @@ -2008,22 +1986,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState2: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 3/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 3/8"; } auto result = prior.prior.prior.prior.prior.current_promise(); PromiseResult2* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 3/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits2::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits2::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 3/8 gets " + << (p != nullptr + ? (PromiseResultTraits2::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits2::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits2::IsOk(*p)) { @@ -2041,22 +2018,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState3: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 4/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 4/8"; } auto result = prior.prior.prior.prior.current_promise(); PromiseResult3* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 4/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits3::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits3::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 4/8 gets " + << (p != nullptr + ? (PromiseResultTraits3::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits3::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits3::IsOk(*p)) { @@ -2073,22 +2049,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState4: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 5/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 5/8"; } auto result = prior.prior.prior.current_promise(); PromiseResult4* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 5/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits4::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits4::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 5/8 gets " + << (p != nullptr + ? (PromiseResultTraits4::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits4::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits4::IsOk(*p)) { @@ -2105,22 +2080,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState5: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 6/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 6/8"; } auto result = prior.prior.current_promise(); PromiseResult5* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 6/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits5::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits5::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 6/8 gets " + << (p != nullptr + ? (PromiseResultTraits5::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits5::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits5::IsOk(*p)) { @@ -2137,22 +2111,21 @@ struct SeqState { ABSL_FALLTHROUGH_INTENDED; case State::kState6: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 7/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 7/8"; } auto result = prior.current_promise(); PromiseResult6* p = result.value_if_ready(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log( - whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 7/8 gets %s", this, - p != nullptr - ? (PromiseResultTraits6::IsOk(*p) - ? "ready" - : absl::StrCat("early-error:", - PromiseResultTraits6::ErrorString(*p)) - .c_str()) - : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 7/8 gets " + << (p != nullptr + ? (PromiseResultTraits6::IsOk(*p) + ? "ready" + : absl::StrCat( + "early-error:", + PromiseResultTraits6::ErrorString(*p))) + : "pending"); } if (p == nullptr) return Pending{}; if (!PromiseResultTraits6::IsOk(*p)) { @@ -2170,14 +2143,14 @@ struct SeqState { default: case State::kState7: { if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: begin poll step 8/8", this); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: begin poll step 8/8"; } auto result = current_promise(); if (grpc_trace_promise_primitives.enabled()) { - gpr_log(whence.file(), whence.line(), GPR_LOG_SEVERITY_INFO, - "seq[%p]: poll step 8/8 gets %s", this, - result.ready() ? "ready" : "pending"); + LOG(INFO).AtLocation(whence.file(), whence.line()) + << "seq[" << this << "]: poll step 8/8 gets " + << (result.ready() ? "ready" : "pending"); } auto* p = result.value_if_ready(); if (p == nullptr) return Pending{}; diff --git a/src/core/lib/promise/status_flag.h b/src/core/lib/promise/status_flag.h index 38d4cf5b720..132b2079c07 100644 --- a/src/core/lib/promise/status_flag.h +++ b/src/core/lib/promise/status_flag.h @@ -171,6 +171,8 @@ class ValueOrFailure { T& value() { return value_.value(); } const T& operator*() const { return *value_; } T& operator*() { return *value_; } + const T* operator->() const { return &*value_; } + T* operator->() { return &*value_; } bool operator==(const ValueOrFailure& other) const { return value_ == other.value_; diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.cc b/src/core/lib/security/credentials/jwt/jwt_verifier.cc index 0e927aa075d..49cc8e21be1 100644 --- a/src/core/lib/security/credentials/jwt/jwt_verifier.cc +++ b/src/core/lib/security/credentials/jwt/jwt_verifier.cc @@ -42,6 +42,7 @@ #endif #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/escaping.h" @@ -114,7 +115,7 @@ static const EVP_MD* evp_md_from_alg(const char* alg) { static Json parse_json_part_from_jwt(const char* str, size_t len) { std::string string; if (!absl::WebSafeBase64Unescape(absl::string_view(str, len), &string)) { - gpr_log(GPR_ERROR, "Invalid base64."); + LOG(ERROR) << "Invalid base64."; return Json(); // JSON null } auto json = grpc_core::JsonParse(string); @@ -163,13 +164,13 @@ static jose_header* jose_header_from_json(Json json) { Json::Object::const_iterator it; jose_header* h = grpc_core::Zalloc(); if (json.type() != Json::Type::kObject) { - gpr_log(GPR_ERROR, "JSON value is not an object"); + LOG(ERROR) << "JSON value is not an object"; goto error; } // Check alg field. it = json.object().find("alg"); if (it == json.object().end()) { - gpr_log(GPR_ERROR, "Missing alg field."); + LOG(ERROR) << "Missing alg field."; goto error; } // We only support RSA-1.5 signatures for now. @@ -180,7 +181,7 @@ static jose_header* jose_header_from_json(Json json) { if (it->second.type() != Json::Type::kString || strncmp(alg_value, "RS", 2) != 0 || evp_md_from_alg(alg_value) == nullptr) { - gpr_log(GPR_ERROR, "Invalid alg field"); + LOG(ERROR) << "Invalid alg field"; goto error; } h->alg = alg_value; @@ -319,13 +320,13 @@ grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims* claims, skewed_now = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); if (gpr_time_cmp(skewed_now, claims->nbf) < 0) { - gpr_log(GPR_ERROR, "JWT is not valid yet."); + LOG(ERROR) << "JWT is not valid yet."; return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; } skewed_now = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_clock_skew); if (gpr_time_cmp(skewed_now, claims->exp) > 0) { - gpr_log(GPR_ERROR, "JWT is expired."); + LOG(ERROR) << "JWT is expired."; return GRPC_JWT_VERIFIER_TIME_CONSTRAINT_FAILURE; } @@ -430,7 +431,7 @@ struct grpc_jwt_verifier { static Json json_from_http(const grpc_http_response* response) { if (response == nullptr) { - gpr_log(GPR_ERROR, "HTTP response is NULL."); + LOG(ERROR) << "HTTP response is NULL."; return Json(); // JSON null } if (response->status != 200) { @@ -441,7 +442,7 @@ static Json json_from_http(const grpc_http_response* response) { auto json = grpc_core::JsonParse( absl::string_view(response->body, response->body_length)); if (!json.ok()) { - gpr_log(GPR_ERROR, "Invalid JSON found in response."); + LOG(ERROR) << "Invalid JSON found in response."; return Json(); // JSON null } return std::move(*json); @@ -464,12 +465,12 @@ static EVP_PKEY* extract_pkey_from_x509(const char* x509_str) { BIO_write(bio, x509_str, static_cast(len)); x509 = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); if (x509 == nullptr) { - gpr_log(GPR_ERROR, "Unable to parse x509 cert."); + LOG(ERROR) << "Unable to parse x509 cert."; goto end; } result = X509_get_pubkey(x509); if (result == nullptr) { - gpr_log(GPR_ERROR, "Cannot find public key in X509 cert."); + LOG(ERROR) << "Cannot find public key in X509 cert."; } end: @@ -482,7 +483,7 @@ static BIGNUM* bignum_from_base64(const char* b64) { if (b64 == nullptr) return nullptr; std::string string; if (!absl::WebSafeBase64Unescape(b64, &string)) { - gpr_log(GPR_ERROR, "Invalid base64 for big num."); + LOG(ERROR) << "Invalid base64 for big num."; return nullptr; } return BN_bin2bn(reinterpret_cast(string.data()), @@ -540,27 +541,27 @@ static EVP_PKEY* pkey_from_jwk(const Json& json, const char* kty) { #if OPENSSL_VERSION_NUMBER < 0x30000000L rsa = RSA_new(); if (rsa == nullptr) { - gpr_log(GPR_ERROR, "Could not create rsa key."); + LOG(ERROR) << "Could not create rsa key."; goto end; } #endif it = json.object().find("n"); if (it == json.object().end()) { - gpr_log(GPR_ERROR, "Missing RSA public key field."); + LOG(ERROR) << "Missing RSA public key field."; goto end; } tmp_n = bignum_from_base64(validate_string_field(it->second, "n")); if (tmp_n == nullptr) goto end; it = json.object().find("e"); if (it == json.object().end()) { - gpr_log(GPR_ERROR, "Missing RSA public key field."); + LOG(ERROR) << "Missing RSA public key field."; goto end; } tmp_e = bignum_from_base64(validate_string_field(it->second, "e")); if (tmp_e == nullptr) goto end; #if OPENSSL_VERSION_NUMBER < 0x30000000L if (!RSA_set0_key(rsa, tmp_n, tmp_e, nullptr)) { - gpr_log(GPR_ERROR, "Cannot set RSA key from inputs."); + LOG(ERROR) << "Cannot set RSA key from inputs."; goto end; } // RSA_set0_key takes ownership on success. @@ -573,21 +574,21 @@ static EVP_PKEY* pkey_from_jwk(const Json& json, const char* kty) { if (!OSSL_PARAM_BLD_push_BN(bld, "n", tmp_n) || !OSSL_PARAM_BLD_push_BN(bld, "e", tmp_e) || (params = OSSL_PARAM_BLD_to_param(bld)) == NULL) { - gpr_log(GPR_ERROR, "Could not create OSSL_PARAM"); + LOG(ERROR) << "Could not create OSSL_PARAM"; goto end; } ctx = EVP_PKEY_CTX_new_from_name(nullptr, "RSA", nullptr); if (ctx == nullptr) { - gpr_log(GPR_ERROR, "Could not create rsa key."); + LOG(ERROR) << "Could not create rsa key."; goto end; } if (EVP_PKEY_fromdata_init(ctx) <= 0) { - gpr_log(GPR_ERROR, "Could not create rsa key."); + LOG(ERROR) << "Could not create rsa key."; goto end; } if (EVP_PKEY_fromdata(ctx, &result, EVP_PKEY_KEYPAIR, params) <= 0) { - gpr_log(GPR_ERROR, "Cannot set RSA key from inputs."); + LOG(ERROR) << "Cannot set RSA key from inputs."; goto end; } #endif @@ -618,8 +619,7 @@ static EVP_PKEY* find_verification_key(const Json& json, const char* header_alg, return extract_pkey_from_x509(cur->string().c_str()); } if (jwt_keys->type() != Json::Type::kArray) { - gpr_log(GPR_ERROR, - "Unexpected value type of keys property in jwks key set."); + LOG(ERROR) << "Unexpected value type of keys property in jwks key set."; return nullptr; } // Key format is specified in: @@ -661,21 +661,21 @@ static int verify_jwt_signature(EVP_PKEY* key, const char* alg, CHECK_NE(md, nullptr); // Checked before. if (md_ctx == nullptr) { - gpr_log(GPR_ERROR, "Could not create EVP_MD_CTX."); + LOG(ERROR) << "Could not create EVP_MD_CTX."; goto end; } if (EVP_DigestVerifyInit(md_ctx, nullptr, md, nullptr, key) != 1) { - gpr_log(GPR_ERROR, "EVP_DigestVerifyInit failed."); + LOG(ERROR) << "EVP_DigestVerifyInit failed."; goto end; } if (EVP_DigestVerifyUpdate(md_ctx, GRPC_SLICE_START_PTR(signed_data), GRPC_SLICE_LENGTH(signed_data)) != 1) { - gpr_log(GPR_ERROR, "EVP_DigestVerifyUpdate failed."); + LOG(ERROR) << "EVP_DigestVerifyUpdate failed."; goto end; } if (EVP_DigestVerifyFinal(md_ctx, GRPC_SLICE_START_PTR(signature), GRPC_SLICE_LENGTH(signature)) != 1) { - gpr_log(GPR_ERROR, "JWT signature verification failed."); + LOG(ERROR) << "JWT signature verification failed."; goto end; } @@ -742,7 +742,7 @@ static void on_openid_config_retrieved(void* user_data, if (json.type() == Json::Type::kNull) goto error; cur = find_property_by_name(json, "jwks_uri"); if (cur == nullptr) { - gpr_log(GPR_ERROR, "Could not find jwks_uri in openid config."); + LOG(ERROR) << "Could not find jwks_uri in openid config."; goto error; } jwks_uri = validate_string_field(*cur, "jwks_uri"); @@ -843,11 +843,11 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) { CHECK(ctx != nullptr && ctx->header != nullptr && ctx->claims != nullptr); iss = ctx->claims->iss; if (ctx->header->kid == nullptr) { - gpr_log(GPR_ERROR, "Missing kid in jose header."); + LOG(ERROR) << "Missing kid in jose header."; goto error; } if (iss == nullptr) { - gpr_log(GPR_ERROR, "Missing iss in claims."); + LOG(ERROR) << "Missing iss in claims."; goto error; } @@ -862,7 +862,7 @@ static void retrieve_key_and_verify(verifier_cb_ctx* ctx) { CHECK_NE(ctx->verifier, nullptr); mapping = verifier_get_mapping(ctx->verifier, email_domain); if (mapping == nullptr) { - gpr_log(GPR_ERROR, "Missing mapping for issuer email."); + LOG(ERROR) << "Missing mapping for issuer email."; goto error; } host = gpr_strdup(mapping->key_url_prefix); diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index 4c425b87470..0d268a21572 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -34,6 +34,7 @@ #include "absl/base/thread_annotations.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -124,7 +125,7 @@ using GrpcClosure = Closure; Call::ParentCall* Call::GetOrCreateParentCall() { ParentCall* p = parent_call_.load(std::memory_order_acquire); if (p == nullptr) { - p = arena_->New(); + p = arena()->New(); ParentCall* expected = nullptr; if (!parent_call_.compare_exchange_strong(expected, p, std::memory_order_release, @@ -243,28 +244,6 @@ void Call::PropagateCancellationToChildren() { } } -char* Call::GetPeer() { - Slice peer_slice = GetPeerString(); - if (!peer_slice.empty()) { - absl::string_view peer_string_view = peer_slice.as_string_view(); - char* peer_string = - static_cast(gpr_malloc(peer_string_view.size() + 1)); - memcpy(peer_string, peer_string_view.data(), peer_string_view.size()); - peer_string[peer_string_view.size()] = '\0'; - return peer_string; - } - char* peer_string = grpc_channel_get_target(channel_->c_ptr()); - if (peer_string != nullptr) return peer_string; - return gpr_strdup("unknown"); -} - -void Call::DeleteThis() { - RefCountedPtr channel = std::move(channel_); - Arena* arena = arena_; - this->~Call(); - channel->DestroyArena(arena); -} - void Call::PrepareOutgoingInitialMetadata(const grpc_op& op, grpc_metadata_batch& md) { // TODO(juanlishen): If the user has already specified a compression @@ -279,7 +258,7 @@ void Call::PrepareOutgoingInitialMetadata(const grpc_op& op, op.data.send_initial_metadata.maybe_compression_level.level; level_set = true; } else { - const grpc_compression_options copts = channel()->compression_options(); + const grpc_compression_options copts = compression_options(); if (copts.default_level.is_set) { level_set = true; effective_compression_level = copts.default_level.level; @@ -311,13 +290,12 @@ void Call::ProcessIncomingInitialMetadata(grpc_metadata_batch& md) { md.Take(GrpcAcceptEncodingMetadata()) .value_or(CompressionAlgorithmSet{GRPC_COMPRESS_NONE}); - const grpc_compression_options compression_options = - channel_->compression_options(); + const grpc_compression_options copts = compression_options(); const grpc_compression_algorithm compression_algorithm = incoming_compression_algorithm_; - if (GPR_UNLIKELY(!CompressionAlgorithmSet::FromUint32( - compression_options.enabled_algorithms_bitset) - .IsSet(compression_algorithm))) { + if (GPR_UNLIKELY( + !CompressionAlgorithmSet::FromUint32(copts.enabled_algorithms_bitset) + .IsSet(compression_algorithm))) { // check if algorithm is supported by current channel config HandleCompressionAlgorithmDisabled(compression_algorithm); } @@ -367,22 +345,20 @@ void Call::UpdateDeadline(Timestamp deadline) { StatusIntProperty::kRpcStatus, GRPC_STATUS_DEADLINE_EXCEEDED)); return; } - auto* const event_engine = channel()->event_engine(); if (deadline_ != Timestamp::InfFuture()) { - if (!event_engine->Cancel(deadline_task_)) return; + if (!event_engine_->Cancel(deadline_task_)) return; } else { InternalRef("deadline"); } deadline_ = deadline; - deadline_task_ = event_engine->RunAfter(deadline - Timestamp::Now(), this); + deadline_task_ = event_engine_->RunAfter(deadline - Timestamp::Now(), this); } void Call::ResetDeadline() { { MutexLock lock(&deadline_mu_); if (deadline_ == Timestamp::InfFuture()) return; - auto* const event_engine = channel()->event_engine(); - if (!event_engine->Cancel(deadline_task_)) return; + if (!event_engine_->Cancel(deadline_task_)) return; deadline_ = Timestamp::InfFuture(); } InternalUnref("deadline[reset]"); @@ -397,11 +373,69 @@ void Call::Run() { InternalUnref("deadline[run]"); } +/////////////////////////////////////////////////////////////////////////////// +// ChannelBasedCall +// TODO(ctiller): once we remove the v2 client code this can be folded into +// FilterStackCall + +class ChannelBasedCall : public Call { + protected: + ChannelBasedCall(Arena* arena, bool is_client, Timestamp send_deadline, + RefCountedPtr channel) + : Call(is_client, send_deadline, channel->event_engine()), + arena_(arena), + channel_(std::move(channel)) { + DCHECK_NE(arena_, nullptr); + } + + Arena* arena() final { return arena_; } + + char* GetPeer() final { + Slice peer_slice = GetPeerString(); + if (!peer_slice.empty()) { + absl::string_view peer_string_view = peer_slice.as_string_view(); + char* peer_string = + static_cast(gpr_malloc(peer_string_view.size() + 1)); + memcpy(peer_string, peer_string_view.data(), peer_string_view.size()); + peer_string[peer_string_view.size()] = '\0'; + return peer_string; + } + char* peer_string = grpc_channel_get_target(channel_->c_ptr()); + if (peer_string != nullptr) return peer_string; + return gpr_strdup("unknown"); + } + + grpc_event_engine::experimental::EventEngine* event_engine() const override { + return channel_->event_engine(); + } + + grpc_compression_options compression_options() override { + return channel_->compression_options(); + } + + void DeleteThis() { + RefCountedPtr channel = std::move(channel_); + Arena* arena = arena_; + this->~ChannelBasedCall(); + channel->DestroyArena(arena); + } + + Channel* channel() const { return channel_.get(); } + + protected: + // Non-virtual arena accessor -- needed by PipeBasedCall + Arena* GetArena() { return arena_; } + + private: + Arena* const arena_; + RefCountedPtr channel_; +}; + /////////////////////////////////////////////////////////////////////////////// // FilterStackCall // To be removed once promise conversion is complete -class FilterStackCall final : public Call { +class FilterStackCall final : public ChannelBasedCall { public: ~FilterStackCall() override { for (int i = 0; i < GRPC_CONTEXT_COUNT; ++i) { @@ -430,10 +464,6 @@ class FilterStackCall final : public Call { GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(*this))); } - grpc_event_engine::experimental::EventEngine* event_engine() const override { - return channel()->event_engine(); - } - grpc_call_element* call_elem(size_t idx) { return grpc_call_stack_element(call_stack(), idx); } @@ -569,8 +599,8 @@ class FilterStackCall final : public Call { }; FilterStackCall(Arena* arena, const grpc_call_create_args& args) - : Call(arena, args.server_transport_data == nullptr, args.send_deadline, - args.channel->Ref()), + : ChannelBasedCall(arena, args.server_transport_data == nullptr, + args.send_deadline, args.channel->Ref()), cq_(args.cq), stream_op_payload_(context_) { context_[GRPC_CONTEXT_CALL].value = this; @@ -1138,8 +1168,7 @@ void FilterStackCall::RecvTrailingFilter(grpc_metadata_batch* b, } else if (!is_client()) { SetFinalStatus(absl::OkStatus()); } else { - gpr_log(GPR_DEBUG, - "Received trailing metadata with no error and no status"); + VLOG(2) << "Received trailing metadata with no error and no status"; SetFinalStatus(grpc_error_set_int(GRPC_ERROR_CREATE("No status received"), StatusIntProperty::kRpcStatus, GRPC_STATUS_UNKNOWN)); @@ -1874,15 +1903,15 @@ bool ValidateMetadata(size_t count, grpc_metadata* metadata) { // PromiseBasedCall // Will be folded into Call once the promise conversion is done -class BasicPromiseBasedCall : public Call, public Party { +class BasicPromiseBasedCall : public ChannelBasedCall, public Party { public: using Call::arena; BasicPromiseBasedCall(Arena* arena, uint32_t initial_external_refs, uint32_t initial_internal_refs, const grpc_call_create_args& args) - : Call(arena, args.server_transport_data == nullptr, args.send_deadline, - args.channel->Ref()), + : ChannelBasedCall(arena, args.server_transport_data == nullptr, + args.send_deadline, args.channel->Ref()), Party(initial_internal_refs), external_refs_(initial_external_refs), cq_(args.cq) { @@ -1903,7 +1932,6 @@ class BasicPromiseBasedCall : public Call, public Party { virtual void OrphanCall() = 0; - virtual ServerCallContext* server_call_context() { return nullptr; } void SetCompletionQueue(grpc_completion_queue* cq) final { cq_ = cq; GRPC_CQ_INTERNAL_REF(cq, "bind"); @@ -2533,10 +2561,6 @@ void CallContext::IncrementRefCount(const char* reason) { void CallContext::Unref(const char* reason) { call_->InternalUnref(reason); } -ServerCallContext* CallContext::server_call_context() { - return call_->server_call_context(); -} - RefCountedPtr CallContext::MakeCallSpine( CallArgs call_args) { return call_->MakeCallSpine(std::move(call_args)); @@ -2780,12 +2804,12 @@ class ClientPromiseBasedCall final : public PromiseBasedCall { void PublishInitialMetadata(ServerMetadata* metadata); ClientMetadataHandle send_initial_metadata_; - Pipe server_initial_metadata_{arena()}; + Pipe server_initial_metadata_{GetArena()}; Latch server_trailing_metadata_; Latch cancel_error_; Latch polling_entity_; - Pipe client_to_server_messages_{arena()}; - Pipe server_to_client_messages_{arena()}; + Pipe client_to_server_messages_{GetArena()}; + Pipe server_to_client_messages_{GetArena()}; bool is_trailers_only_ = false; bool scheduled_receive_status_ = false; bool scheduled_send_close_ = false; @@ -3092,242 +3116,7 @@ void ClientPromiseBasedCall::StartRecvStatusOnClient( #endif /////////////////////////////////////////////////////////////////////////////// -// ServerPromiseBasedCall - -#ifdef GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL - -class ServerPromiseBasedCall final : public PromiseBasedCall, - public ServerCallContext { - public: - ServerPromiseBasedCall(Arena* arena, grpc_call_create_args* args); - - void OrphanCall() override {} - void CancelWithError(grpc_error_handle) override; - grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag, - bool is_notify_tag_closure) override; - bool is_trailers_only() const override { - Crash("is_trailers_only not implemented for server calls"); - } - absl::string_view GetServerAuthority() const override { - const Slice* authority_metadata = - client_initial_metadata_->get_pointer(HttpAuthorityMetadata()); - if (authority_metadata == nullptr) return ""; - return authority_metadata->as_string_view(); - } - - // Polling order for the server promise stack: - // - // │ ┌───────────────────────────────────────┐ - // │ │ ServerPromiseBasedCall ├──► Lifetime management - // │ ├───────────────────────────────────────┤ - // │ │ ConnectedChannel ├─┐ - // │ ├───────────────────────────────────────┤ └► Interactions with the - // │ │ ... closest to transport filter │ transport - send/recv msgs - // │ ├───────────────────────────────────────┤ and metadata, call phase - // │ │ ... │ ordering - // │ ├───────────────────────────────────────┤ - // │ │ ... closest to app filter │ ┌► Request matching, initial - // │ ├───────────────────────────────────────┤ │ setup, publishing call to - // │ │ Server::ChannelData::MakeCallPromise ├─┘ application - // │ ├───────────────────────────────────────┤ - // │ │ MakeTopOfServerCallPromise ├──► Send trailing metadata - // ▼ └───────────────────────────────────────┘ - // Polling & - // instantiation - // order - - std::string DebugTag() const override { - return absl::StrFormat("SERVER_CALL[%p]: ", this); - } - - ServerCallContext* server_call_context() override { return this; } - - const void* server_stream_data() override { return server_transport_data_; } - void PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) override; - ArenaPromise MakeTopOfServerCallPromise( - CallArgs call_args, grpc_completion_queue* cq, - absl::FunctionRef publish) override; - - private: - class RecvCloseOpCancelState { - public: - // Request that receiver be filled in per - // grpc_op_recv_close_on_server. Returns true if the request can - // be fulfilled immediately. Returns false if the request will be - // fulfilled later. - bool ReceiveCloseOnServerOpStarted(int* receiver) { - uintptr_t state = state_.load(std::memory_order_acquire); - uintptr_t new_state; - do { - switch (state) { - case kUnset: - new_state = reinterpret_cast(receiver); - break; - case kFinishedWithFailure: - *receiver = 1; - return true; - case kFinishedWithSuccess: - *receiver = 0; - return true; - default: - Crash("Two threads offered ReceiveCloseOnServerOpStarted"); - } - } while (!state_.compare_exchange_weak(state, new_state, - std::memory_order_acq_rel, - std::memory_order_acquire)); - return false; - } - - // Mark the call as having completed. - // Returns true if this finishes a previous - // RequestReceiveCloseOnServer. - bool CompleteCallWithCancelledSetTo(bool cancelled) { - uintptr_t state = state_.load(std::memory_order_acquire); - uintptr_t new_state; - bool r; - do { - switch (state) { - case kUnset: - new_state = cancelled ? kFinishedWithFailure : kFinishedWithSuccess; - r = false; - break; - case kFinishedWithFailure: - return false; - case kFinishedWithSuccess: - Crash("unreachable"); - default: - new_state = cancelled ? kFinishedWithFailure : kFinishedWithSuccess; - r = true; - } - } while (!state_.compare_exchange_weak(state, new_state, - std::memory_order_acq_rel, - std::memory_order_acquire)); - if (r) *reinterpret_cast(state) = cancelled ? 1 : 0; - return r; - } - - std::string ToString() const { - auto state = state_.load(std::memory_order_relaxed); - switch (state) { - case kUnset: - return "Unset"; - case kFinishedWithFailure: - return "FinishedWithFailure"; - case kFinishedWithSuccess: - return "FinishedWithSuccess"; - default: - return absl::StrFormat("WaitingForReceiver(%p)", - reinterpret_cast(state)); - } - } - - private: - static constexpr uintptr_t kUnset = 0; - static constexpr uintptr_t kFinishedWithFailure = 1; - static constexpr uintptr_t kFinishedWithSuccess = 2; - // Holds one of kUnset, kFinishedWithFailure, or - // kFinishedWithSuccess OR an int* that wants to receive the - // final status. - std::atomic state_{kUnset}; - }; - - void CommitBatch(const grpc_op* ops, size_t nops, - const Completion& completion); - void Finish(ServerMetadataHandle result); - - ServerInterface* const server_; - const void* const server_transport_data_; - PipeSender* server_initial_metadata_ = nullptr; - PipeSender* server_to_client_messages_ = nullptr; - PipeReceiver* client_to_server_messages_ = nullptr; - Latch send_trailing_metadata_; - RecvCloseOpCancelState recv_close_op_cancel_state_; - ClientMetadataHandle client_initial_metadata_; - Completion recv_close_completion_; - std::atomic cancelled_{false}; -}; - -ServerPromiseBasedCall::ServerPromiseBasedCall(Arena* arena, - grpc_call_create_args* args) - : PromiseBasedCall(arena, 0, *args), - server_(args->server), - server_transport_data_(args->server_transport_data) { - global_stats().IncrementServerCallsCreated(); - channelz::ServerNode* channelz_node = server_->channelz_node(); - if (channelz_node != nullptr) { - channelz_node->RecordCallStarted(); - } - ScopedContext activity_context(this); - // TODO(yashykt): In the future, we want to also enable stats and trace - // collecting from when the call is created at the transport. The idea is that - // the transport would create the call tracer and pass it in as part of the - // metadata. - // TODO(yijiem): OpenCensus and internal Census is still using this way to - // set server call tracer. We need to refactor them to stats plugins - // (including removing the client channel filters). - if (args->server != nullptr && - args->server->server_call_tracer_factory() != nullptr) { - auto* server_call_tracer = - args->server->server_call_tracer_factory()->CreateNewServerCallTracer( - arena, args->server->channel_args()); - if (server_call_tracer != nullptr) { - // Note that we are setting both - // GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE and - // GRPC_CONTEXT_CALL_TRACER as a matter of convenience. In the future - // promise-based world, we would just a single tracer object for each - // stack (call, subchannel_call, server_call.) - ContextSet(GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE, - server_call_tracer, nullptr); - ContextSet(GRPC_CONTEXT_CALL_TRACER, server_call_tracer, nullptr); - } - } - args->channel->channel_stack()->stats_plugin_group->AddServerCallTracers( - context()); - Spawn("server_promise", - channel()->channel_stack()->MakeServerCallPromise( - CallArgs{nullptr, ClientInitialMetadataOutstandingToken::Empty(), - nullptr, nullptr, nullptr, nullptr}), - [this](ServerMetadataHandle result) { Finish(std::move(result)); }); -} - -void ServerPromiseBasedCall::Finish(ServerMetadataHandle result) { - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] Finish: recv_close_state:%s result:%s", - DebugTag().c_str(), recv_close_op_cancel_state_.ToString().c_str(), - result->DebugString().c_str()); - } - const auto status = - result->get(GrpcStatusMetadata()).value_or(GRPC_STATUS_UNKNOWN); - channelz::ServerNode* channelz_node = server_->channelz_node(); - if (channelz_node != nullptr) { - if (status == GRPC_STATUS_OK) { - channelz_node->RecordCallSucceeded(); - } else { - channelz_node->RecordCallFailed(); - } - } - bool was_cancelled = result->get(GrpcCallWasCancelled()).value_or(true); - if (recv_close_op_cancel_state_.CompleteCallWithCancelledSetTo( - was_cancelled)) { - FinishOpOnCompletion(&recv_close_completion_, - PendingOp::kReceiveCloseOnServer); - } - if (was_cancelled) set_failed_before_recv_message(); - if (server_initial_metadata_ != nullptr) { - server_initial_metadata_->Close(); - } - Slice message_slice; - if (Slice* message = result->get_pointer(GrpcMessageMetadata())) { - message_slice = message->Ref(); - } - AcceptTransportStatsFromContext(); - SetFinalizationStatus(status, std::move(message_slice)); - set_completed(); - ResetDeadline(); - PropagateCancellationToChildren(); -} +// CallSpine based Server Call grpc_call_error ValidateServerBatch(const grpc_op* ops, size_t nops) { BitSet<8> got_ops; @@ -3371,234 +3160,33 @@ grpc_call_error ValidateServerBatch(const grpc_op* ops, size_t nops) { return GRPC_CALL_OK; } -void ServerPromiseBasedCall::CommitBatch(const grpc_op* ops, size_t nops, - const Completion& completion) { - Party::BulkSpawner spawner(this); - for (size_t op_idx = 0; op_idx < nops; op_idx++) { - const grpc_op& op = ops[op_idx]; - switch (op.op) { - case GRPC_OP_SEND_INITIAL_METADATA: { - auto metadata = arena()->MakePooled(); - PrepareOutgoingInitialMetadata(op, *metadata); - CToMetadata(op.data.send_initial_metadata.metadata, - op.data.send_initial_metadata.count, metadata.get()); - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] Send initial metadata", - DebugTag().c_str()); - } - QueueSend(); - spawner.Spawn( - "call_send_initial_metadata", - [this, metadata = std::move(metadata)]() mutable { - EnactSend(); - return server_initial_metadata_->Push(std::move(metadata)); - }, - [this, - completion = AddOpToCompletion( - completion, PendingOp::kSendInitialMetadata)](bool r) mutable { - if (!r) { - set_failed_before_recv_message(); - FailCompletion(completion); - } - FinishOpOnCompletion(&completion, - PendingOp::kSendInitialMetadata); - }); - } break; - case GRPC_OP_SEND_MESSAGE: - StartSendMessage(op, completion, server_to_client_messages_, spawner); - break; - case GRPC_OP_RECV_MESSAGE: - if (cancelled_.load(std::memory_order_relaxed)) { - set_failed_before_recv_message(); - FailCompletion(completion); - break; - } - StartRecvMessage( - op, completion, []() { return []() { return Empty{}; }; }, - client_to_server_messages_, true, spawner); - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: { - auto metadata = arena()->MakePooled(); - CToMetadata(op.data.send_status_from_server.trailing_metadata, - op.data.send_status_from_server.trailing_metadata_count, - metadata.get()); - metadata->Set(GrpcStatusMetadata(), - op.data.send_status_from_server.status); - if (auto* details = op.data.send_status_from_server.status_details) { - // TODO(ctiller): this should not be a copy, but we have callers that - // allocate and pass in a slice created with - // grpc_slice_from_static_string and then delete the string after - // passing it in, which shouldn't be a supported API. - metadata->Set(GrpcMessageMetadata(), - Slice(grpc_slice_copy(*details))); - } - spawner.Spawn( - "call_send_status_from_server", - [this, metadata = std::move(metadata)]() mutable { - bool r = true; - if (send_trailing_metadata_.is_set()) { - r = false; - } else { - send_trailing_metadata_.Set(std::move(metadata)); - } - return Map(WaitForSendingStarted(), [this, r](Empty) { - server_initial_metadata_->Close(); - server_to_client_messages_->Close(); - return r; - }); - }, - [this, completion = AddOpToCompletion( - completion, PendingOp::kSendStatusFromServer)]( - bool ok) mutable { - if (!ok) { - set_failed_before_recv_message(); - FailCompletion(completion); - } - FinishOpOnCompletion(&completion, - PendingOp::kSendStatusFromServer); - }); - } break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] StartBatch: RecvClose %s", - DebugTag().c_str(), - recv_close_op_cancel_state_.ToString().c_str()); - } - ForceCompletionSuccess(completion); - recv_close_completion_ = - AddOpToCompletion(completion, PendingOp::kReceiveCloseOnServer); - if (recv_close_op_cancel_state_.ReceiveCloseOnServerOpStarted( - op.data.recv_close_on_server.cancelled)) { - FinishOpOnCompletion(&recv_close_completion_, - PendingOp::kReceiveCloseOnServer); - } - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - case GRPC_OP_RECV_INITIAL_METADATA: - abort(); // unreachable - } - } -} - -grpc_call_error ServerPromiseBasedCall::StartBatch(const grpc_op* ops, - size_t nops, - void* notify_tag, - bool is_notify_tag_closure) { - if (nops == 0) { - EndOpImmediately(cq(), notify_tag, is_notify_tag_closure); - return GRPC_CALL_OK; - } - const grpc_call_error validation_result = ValidateServerBatch(ops, nops); - if (validation_result != GRPC_CALL_OK) { - return validation_result; - } - Completion completion = - StartCompletion(notify_tag, is_notify_tag_closure, ops); - CommitBatch(ops, nops, completion); - FinishOpOnCompletion(&completion, PendingOp::kStartingBatch); - return GRPC_CALL_OK; -} - -void ServerPromiseBasedCall::CancelWithError(absl::Status error) { - cancelled_.store(true, std::memory_order_relaxed); - Spawn( - "cancel_with_error", - [this, error = std::move(error)]() { - if (!send_trailing_metadata_.is_set()) { - auto md = ServerMetadataFromStatus(error); - md->Set(GrpcCallWasCancelled(), true); - send_trailing_metadata_.Set(std::move(md)); - } - if (server_to_client_messages_ != nullptr) { - server_to_client_messages_->Close(); - } - if (server_initial_metadata_ != nullptr) { - server_initial_metadata_->Close(); - } - return Empty{}; - }, - [](Empty) {}); -} -#endif - -#ifdef GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL -void ServerPromiseBasedCall::PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) { - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] PublishInitialMetadata: %s", DebugTag().c_str(), - metadata->DebugString().c_str()); - } - PublishMetadataArray(metadata.get(), publish_initial_metadata, false); - client_initial_metadata_ = std::move(metadata); -} - -ArenaPromise -ServerPromiseBasedCall::MakeTopOfServerCallPromise( - CallArgs call_args, grpc_completion_queue* cq, - absl::FunctionRef publish) { - SetCompletionQueue(cq); - call_args.polling_entity->Set( - grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq))); - server_to_client_messages_ = call_args.server_to_client_messages; - client_to_server_messages_ = call_args.client_to_server_messages; - server_initial_metadata_ = call_args.server_initial_metadata; - absl::optional deadline = - client_initial_metadata_->get(GrpcTimeoutMetadata()); - if (deadline.has_value()) { - set_send_deadline(*deadline); - UpdateDeadline(*deadline); - } - ProcessIncomingInitialMetadata(*client_initial_metadata_); - ExternalRef(); - publish(c_ptr()); - return Seq(server_to_client_messages_->AwaitClosed(), - send_trailing_metadata_.Wait()); -} - -/////////////////////////////////////////////////////////////////////////////// -// CallSpine based Server Call - -class ServerCallSpine final : public PipeBasedCallSpine, - public ServerCallContext, - public BasicPromiseBasedCall { +class ServerCall final : public Call, public DualRefCounted { public: - ServerCallSpine(ClientMetadataHandle client_initial_metadata, - ServerInterface* server, Channel* channel, Arena* arena); - - // CallSpineInterface - Pipe& client_initial_metadata() override { - return client_initial_metadata_; - } - Pipe& server_initial_metadata() override { - return server_initial_metadata_; - } - Pipe& client_to_server_messages() override { - return client_to_server_messages_; - } - Pipe& server_to_client_messages() override { - return server_to_client_messages_; + ServerCall(ClientMetadataHandle client_initial_metadata, + CallHandler call_handler, ServerInterface* server, + grpc_completion_queue* cq) + : Call(false, + client_initial_metadata->get(GrpcTimeoutMetadata()) + .value_or(Timestamp::InfFuture()), + call_handler.event_engine()), + call_handler_(std::move(call_handler)), + client_initial_metadata_stored_(std::move(client_initial_metadata)), + cq_(cq), + server_(server) { + call_handler_.legacy_context()[GRPC_CONTEXT_CALL].value = + static_cast(this); + global_stats().IncrementServerCallsCreated(); } - Latch& cancel_latch() override { return cancel_latch_; } - Latch& was_cancelled_latch() override { return was_cancelled_latch_; } - Party& party() override { return *this; } - Arena* arena() override { return BasicPromiseBasedCall::arena(); } - void IncrementRefCount() override { InternalRef("CallSpine"); } - void Unref() override { InternalUnref("CallSpine"); } - // PromiseBasedCall - void OrphanCall() override { - ResetDeadline(); - CancelWithError(absl::CancelledError()); - } void CancelWithError(grpc_error_handle error) override { - SpawnInfallible("CancelWithError", [this, error = std::move(error)] { - auto status = ServerMetadataFromStatus(error); - status->Set(GrpcCallWasCancelled(), true); - PushServerTrailingMetadata(std::move(status)); - return Empty{}; - }); + call_handler_.SpawnInfallible( + "CancelWithError", + [self = WeakRefAsSubclass(), error = std::move(error)] { + auto status = ServerMetadataFromStatus(error); + status->Set(GrpcCallWasCancelled(), true); + self->call_handler_.PushServerTrailingMetadata(std::move(status)); + return Empty{}; + }); } bool is_trailers_only() const override { Crash("is_trailers_only not implemented for server calls"); @@ -3609,102 +3197,78 @@ class ServerCallSpine final : public PipeBasedCallSpine, grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag, bool is_notify_tag_closure) override; - bool Completed() final { Crash("unimplemented"); } - bool failed_before_recv_message() const final { Crash("unimplemented"); } + Arena* arena() override { return call_handler_.arena(); } - ServerCallContext* server_call_context() override { return this; } - const void* server_stream_data() override { Crash("unimplemented"); } - void PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) override; - ArenaPromise MakeTopOfServerCallPromise( - CallArgs, grpc_completion_queue*, - absl::FunctionRef) override { - Crash("unimplemented"); + grpc_event_engine::experimental::EventEngine* event_engine() const override { + return call_handler_.event_engine(); } - void V2HackToStartCallWithoutACallFilterStack() override {} + void ExternalRef() override { Ref().release(); } + void ExternalUnref() override { Unref(); } + void InternalRef(const char*) override { WeakRef().release(); } + void InternalUnref(const char*) override { WeakUnref(); } - ClientMetadata& UnprocessedClientInitialMetadata() override { - Crash("not for v2"); + void Orphaned() override { + // TODO(ctiller): only when we're not already finished + CancelWithError(absl::CancelledError()); } - bool RunParty() override { - ScopedContext ctx(this); - return Party::RunParty(); + void ContextSet(grpc_context_index elem, void* value, + void (*destroy)(void*)) override { + call_handler_.legacy_context()[elem] = + grpc_call_context_element{value, destroy}; + } + + void* ContextGet(grpc_context_index elem) const override { + return call_handler_.legacy_context()[elem].value; + } + + void SetCompletionQueue(grpc_completion_queue*) override { + Crash("unimplemented"); + } + + grpc_compression_options compression_options() override { + return server_->compression_options(); } + grpc_call_stack* call_stack() override { return nullptr; } + + char* GetPeer() override { + Slice peer_slice = GetPeerString(); + if (!peer_slice.empty()) { + absl::string_view peer_string_view = peer_slice.as_string_view(); + char* peer_string = + static_cast(gpr_malloc(peer_string_view.size() + 1)); + memcpy(peer_string, peer_string_view.data(), peer_string_view.size()); + peer_string[peer_string_view.size()] = '\0'; + return peer_string; + } + return gpr_strdup("unknown"); + } + + bool Completed() final { Crash("unimplemented"); } + bool failed_before_recv_message() const final { Crash("unimplemented"); } + private: void CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag, bool is_notify_tag_closure); - StatusFlag FinishRecvMessage(NextResult result); + StatusFlag FinishRecvMessage( + ValueOrFailure> result); - std::string DebugTag() const override { - return absl::StrFormat("SERVER_CALL_SPINE[%p]: ", this); - } - - // Initial metadata from client to server - Pipe client_initial_metadata_; - // Initial metadata from server to client - Pipe server_initial_metadata_; - // Messages travelling from the application to the transport. - Pipe client_to_server_messages_; - // Messages travelling from the transport to the application. - Pipe server_to_client_messages_; - // Latch that can be set to terminate the call - Latch cancel_latch_; - Latch was_cancelled_latch_; + std::string DebugTag() { return absl::StrFormat("SERVER_CALL[%p]: ", this); } + + CallHandler call_handler_; grpc_byte_buffer** recv_message_ = nullptr; ClientMetadataHandle client_initial_metadata_stored_; + grpc_completion_queue* const cq_; + ServerInterface* const server_; }; -ServerCallSpine::ServerCallSpine(ClientMetadataHandle client_initial_metadata, - ServerInterface* server, Channel* channel, - Arena* arena) - : BasicPromiseBasedCall(arena, 0, 1, - [channel, server]() -> grpc_call_create_args { - grpc_call_create_args args; - args.channel = channel->Ref(); - args.server = server; - args.parent = nullptr; - args.propagation_mask = 0; - args.cq = nullptr; - args.pollset_set_alternative = nullptr; - args.server_transport_data = - &args; // Arbitrary non-null pointer - args.send_deadline = Timestamp::InfFuture(); - return args; - }()), - client_initial_metadata_(arena), - server_initial_metadata_(arena), - client_to_server_messages_(arena), - server_to_client_messages_(arena) { - global_stats().IncrementServerCallsCreated(); - ScopedContext ctx(this); - channel->channel_stack()->InitServerCallSpine(this); - SpawnGuarded("push_client_initial_metadata", - [this, md = std::move(client_initial_metadata)]() mutable { - return Map(client_initial_metadata_.sender.Push(std::move(md)), - [](bool r) { return StatusFlag(r); }); - }); -} - -void ServerCallSpine::PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) { - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%s[call] PublishInitialMetadata: %s", DebugTag().c_str(), - metadata->DebugString().c_str()); - } - PublishMetadataArray(metadata.get(), publish_initial_metadata, false); - client_initial_metadata_stored_ = std::move(metadata); -} - -grpc_call_error ServerCallSpine::StartBatch(const grpc_op* ops, size_t nops, - void* notify_tag, - bool is_notify_tag_closure) { +grpc_call_error ServerCall::StartBatch(const grpc_op* ops, size_t nops, + void* notify_tag, + bool is_notify_tag_closure) { if (nops == 0) { - EndOpImmediately(cq(), notify_tag, is_notify_tag_closure); + EndOpImmediately(cq_, notify_tag, is_notify_tag_closure); return GRPC_CALL_OK; } const grpc_call_error validation_result = ValidateServerBatch(ops, nops); @@ -3716,63 +3280,86 @@ grpc_call_error ServerCallSpine::StartBatch(const grpc_op* ops, size_t nops, } namespace { -template +template class MaybeOpImpl { public: - using SetupResult = decltype(std::declval()(grpc_op())); using PromiseFactory = promise_detail::OncePromiseFactory; using Promise = typename PromiseFactory::Promise; - struct Dismissed {}; - using State = absl::variant; + static_assert(!std::is_same::value, + "PromiseFactory must return a promise"); + + MaybeOpImpl() : state_(State::kDismissed) {} + explicit MaybeOpImpl(SetupResult result) : state_(State::kPromiseFactory) { + Construct(&promise_factory_, std::move(result)); + } - // op_ is garbage but shouldn't be uninitialized - MaybeOpImpl() : state_(Dismissed{}), op_(GRPC_OP_RECV_STATUS_ON_CLIENT) {} - MaybeOpImpl(SetupResult result, grpc_op_type op) - : state_(PromiseFactory(std::move(result))), op_(op) {} + ~MaybeOpImpl() { + switch (state_) { + case State::kDismissed: + break; + case State::kPromiseFactory: + Destruct(&promise_factory_); + break; + case State::kPromise: + Destruct(&promise_); + break; + } + } MaybeOpImpl(const MaybeOpImpl&) = delete; MaybeOpImpl& operator=(const MaybeOpImpl&) = delete; - MaybeOpImpl(MaybeOpImpl&& other) noexcept - : state_(MoveState(other.state_)), op_(other.op_) {} - MaybeOpImpl& operator=(MaybeOpImpl&& other) noexcept { - op_ = other.op_; - if (absl::holds_alternative(state_)) { - state_.template emplace(); - return *this; + MaybeOpImpl(MaybeOpImpl&& other) noexcept : state_(other.state_) { + switch (state_) { + case State::kDismissed: + break; + case State::kPromiseFactory: + Construct(&promise_factory_, std::move(other.promise_factory_)); + break; + case State::kPromise: + Construct(&promise_, std::move(other.promise_)); + break; } - // Can't move after first poll => Promise is not an option - state_.template emplace( - std::move(absl::get(other.state_))); - return *this; } + MaybeOpImpl& operator=(MaybeOpImpl&& other) noexcept = delete; Poll operator()() { - if (absl::holds_alternative(state_)) return Success{}; - if (absl::holds_alternative(state_)) { - auto& factory = absl::get(state_); - auto promise = factory.Make(); - state_.template emplace(std::move(promise)); - } - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%sBeginPoll %s", - Activity::current()->DebugTag().c_str(), OpName(op_).c_str()); - } - auto& promise = absl::get(state_); - auto r = poll_cast(promise()); - if (grpc_call_trace.enabled()) { - gpr_log(GPR_INFO, "%sEndPoll %s --> %s", - Activity::current()->DebugTag().c_str(), OpName(op_).c_str(), + switch (state_) { + case State::kDismissed: + return Success{}; + case State::kPromiseFactory: { + auto promise = promise_factory_.Make(); + Destruct(&promise_factory_); + Construct(&promise_, std::move(promise)); + state_ = State::kPromise; + } + ABSL_FALLTHROUGH_INTENDED; + case State::kPromise: { + if (grpc_call_trace.enabled()) { + gpr_log(GPR_INFO, "%sBeginPoll %s", + Activity::current()->DebugTag().c_str(), OpName()); + } + auto r = poll_cast(promise_()); + if (grpc_call_trace.enabled()) { + gpr_log( + GPR_INFO, "%sEndPoll %s --> %s", + Activity::current()->DebugTag().c_str(), OpName(), r.pending() ? "PENDING" : (r.value().ok() ? "OK" : "FAILURE")); + } + return r; + } } - return r; + GPR_UNREACHABLE_CODE(return Pending{}); } private: - GPR_NO_UNIQUE_ADDRESS State state_; - GPR_NO_UNIQUE_ADDRESS grpc_op_type op_; + enum class State { + kDismissed, + kPromiseFactory, + kPromise, + }; - static std::string OpName(grpc_op_type op) { - switch (op) { + static const char* OpName() { + switch (kOp) { case GRPC_OP_SEND_INITIAL_METADATA: return "SendInitialMetadata"; case GRPC_OP_SEND_MESSAGE: @@ -3790,30 +3377,34 @@ class MaybeOpImpl { case GRPC_OP_RECV_STATUS_ON_CLIENT: return "RecvStatusOnClient"; } - return absl::StrCat("UnknownOp(", op, ")"); + Crash("Unreachable"); } - static State MoveState(State& state) { - if (absl::holds_alternative(state)) return Dismissed{}; - // Can't move after first poll => Promise is not an option - return std::move(absl::get(state)); - } + // gcc-12 has problems with this being a variant + GPR_NO_UNIQUE_ADDRESS State state_; + union { + PromiseFactory promise_factory_; + Promise promise_; + }; }; -// MaybeOp captures a fairly complicated dance we need to do for the batch API. -// We first check if an op is included or not, and if it is, we run the setup -// function in the context of the API call (NOT in the call party). -// This setup function returns a promise factory which we'll then run *in* the +// MaybeOp captures a fairly complicated dance we need to do for the batch +// API. We first check if an op is included or not, and if it is, we run the +// setup function in the context of the API call (NOT in the call party). This +// setup function returns a promise factory which we'll then run *in* the // party to do initial setup, and have it return the promise that we'll // ultimately poll on til completion. // Once we express our surface API in terms of core internal types this whole // dance will go away. -template -auto MaybeOp(const grpc_op* ops, uint8_t idx, SetupFn setup) { - if (idx == 255) { - return MaybeOpImpl(); +template +auto MaybeOp(const grpc_op* ops, const std::array& idxs, + SetupFn setup) { + using SetupResult = decltype(std::declval()(grpc_op())); + if (idxs[op_type] == 255) { + return MaybeOpImpl(); } else { - return MaybeOpImpl(setup(ops[idx]), ops[idx].op); + auto r = setup(ops[idxs[op_type]]); + return MaybeOpImpl(std::move(r)); } } @@ -3851,63 +3442,61 @@ PollBatchLogger LogPollBatch(void* tag, F f) { } } // namespace -StatusFlag ServerCallSpine::FinishRecvMessage( - NextResult result) { - if (result.has_value()) { - MessageHandle& message = *result; - NoteLastMessageFlags(message->flags()); - if ((message->flags() & GRPC_WRITE_INTERNAL_COMPRESS) && - (incoming_compression_algorithm() != GRPC_COMPRESS_NONE)) { - *recv_message_ = grpc_raw_compressed_byte_buffer_create( - nullptr, 0, incoming_compression_algorithm()); - } else { - *recv_message_ = grpc_raw_byte_buffer_create(nullptr, 0); - } - grpc_slice_buffer_move_into(message->payload()->c_slice_buffer(), - &(*recv_message_)->data.raw.slice_buffer); +StatusFlag ServerCall::FinishRecvMessage( + ValueOrFailure> result) { + if (!result.ok()) { if (grpc_call_trace.enabled()) { gpr_log(GPR_INFO, "%s[call] RecvMessage: outstanding_recv " - "finishes: received %" PRIdPTR " byte message", - DebugTag().c_str(), - (*recv_message_)->data.raw.slice_buffer.length); + "finishes: received end-of-stream with error", + DebugTag().c_str()); } + *recv_message_ = nullptr; recv_message_ = nullptr; - return Success{}; + return Failure{}; } - if (result.cancelled()) { + if (!result->has_value()) { if (grpc_call_trace.enabled()) { gpr_log(GPR_INFO, "%s[call] RecvMessage: outstanding_recv " - "finishes: received end-of-stream with error", + "finishes: received end-of-stream", DebugTag().c_str()); } *recv_message_ = nullptr; recv_message_ = nullptr; - return Failure{}; + return Success{}; } + MessageHandle& message = **result; + NoteLastMessageFlags(message->flags()); + if ((message->flags() & GRPC_WRITE_INTERNAL_COMPRESS) && + (incoming_compression_algorithm() != GRPC_COMPRESS_NONE)) { + *recv_message_ = grpc_raw_compressed_byte_buffer_create( + nullptr, 0, incoming_compression_algorithm()); + } else { + *recv_message_ = grpc_raw_byte_buffer_create(nullptr, 0); + } + grpc_slice_buffer_move_into(message->payload()->c_slice_buffer(), + &(*recv_message_)->data.raw.slice_buffer); if (grpc_call_trace.enabled()) { gpr_log(GPR_INFO, "%s[call] RecvMessage: outstanding_recv " - "finishes: received end-of-stream", - DebugTag().c_str()); + "finishes: received %" PRIdPTR " byte message", + DebugTag().c_str(), (*recv_message_)->data.raw.slice_buffer.length); } - *recv_message_ = nullptr; recv_message_ = nullptr; return Success{}; } -void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, - void* notify_tag, - bool is_notify_tag_closure) { +void ServerCall::CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag, + bool is_notify_tag_closure) { std::array got_ops{255, 255, 255, 255, 255, 255, 255, 255}; for (size_t op_idx = 0; op_idx < nops; op_idx++) { const grpc_op& op = ops[op_idx]; got_ops[op.op] = op_idx; } - if (!is_notify_tag_closure) grpc_cq_begin_op(cq(), notify_tag); - auto send_initial_metadata = MaybeOp( - ops, got_ops[GRPC_OP_SEND_INITIAL_METADATA], [this](const grpc_op& op) { + if (!is_notify_tag_closure) grpc_cq_begin_op(cq_, notify_tag); + auto send_initial_metadata = MaybeOp( + ops, got_ops, [this](const grpc_op& op) { auto metadata = arena()->MakePooled(); PrepareOutgoingInitialMetadata(op, *metadata); CToMetadata(op.data.send_initial_metadata.metadata, @@ -3917,27 +3506,22 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, DebugTag().c_str()); } return [this, metadata = std::move(metadata)]() mutable { - return Map(server_initial_metadata_.sender.Push(std::move(metadata)), - [this](bool r) { - server_initial_metadata_.sender.Close(); - return StatusFlag(r); - }); + return call_handler_.PushServerInitialMetadata(std::move(metadata)); }; }); auto send_message = - MaybeOp(ops, got_ops[GRPC_OP_SEND_MESSAGE], [this](const grpc_op& op) { + MaybeOp(ops, got_ops, [this](const grpc_op& op) { SliceBuffer send; grpc_slice_buffer_swap( &op.data.send_message.send_message->data.raw.slice_buffer, send.c_slice_buffer()); auto msg = arena()->MakePooled(std::move(send), op.flags); return [this, msg = std::move(msg)]() mutable { - return Map(server_to_client_messages_.sender.Push(std::move(msg)), - [](bool r) { return StatusFlag(r); }); + return call_handler_.PushMessage(std::move(msg)); }; }); - auto send_trailing_metadata = MaybeOp( - ops, got_ops[GRPC_OP_SEND_STATUS_FROM_SERVER], [this](const grpc_op& op) { + auto send_trailing_metadata = MaybeOp( + ops, got_ops, [this](const grpc_op& op) { auto metadata = arena()->MakePooled(); CToMetadata(op.data.send_status_from_server.trailing_metadata, op.data.send_status_from_server.trailing_metadata_count, @@ -3958,18 +3542,18 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, return [this, metadata = std::move(metadata)]() mutable -> Poll { CHECK(metadata != nullptr); - PushServerTrailingMetadata(std::move(metadata)); + call_handler_.PushServerTrailingMetadata(std::move(metadata)); return Success{}; }; }; }); auto recv_message = - MaybeOp(ops, got_ops[GRPC_OP_RECV_MESSAGE], [this](const grpc_op& op) { + MaybeOp(ops, got_ops, [this](const grpc_op& op) { CHECK_EQ(recv_message_, nullptr); recv_message_ = op.data.recv_message.recv_message; return [this]() mutable { - return Map(client_to_server_messages_.receiver.Next(), - [this](NextResult msg) { + return Map(call_handler_.PullMessage(), + [this](ValueOrFailure> msg) { return FinishRecvMessage(std::move(msg)); }); }; @@ -3980,10 +3564,10 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, std::move(send_trailing_metadata)), std::move(recv_message)); if (got_ops[GRPC_OP_RECV_CLOSE_ON_SERVER] != 255) { - auto recv_trailing_metadata = MaybeOp( - ops, got_ops[GRPC_OP_RECV_CLOSE_ON_SERVER], [this](const grpc_op& op) { + auto recv_trailing_metadata = MaybeOp( + ops, got_ops, [this](const grpc_op& op) { return [this, cancelled = op.data.recv_close_on_server.cancelled]() { - return Map(WasCancelled(), + return Map(call_handler_.WasCancelled(), [cancelled, this](bool result) -> Success { ResetDeadline(); *cancelled = result ? 1 : 0; @@ -3991,7 +3575,7 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, }); }; }); - SpawnInfallible( + call_handler_.SpawnInfallible( "final-batch", [primary_ops = std::move(primary_ops), recv_trailing_metadata = std::move(recv_trailing_metadata), @@ -4001,37 +3585,38 @@ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops, Seq(std::move(primary_ops), std::move(recv_trailing_metadata), [is_notify_tag_closure, notify_tag, this](StatusFlag) { return WaitForCqEndOp(is_notify_tag_closure, notify_tag, - absl::OkStatus(), cq()); + absl::OkStatus(), cq_); })); }); } else { - SpawnInfallible("batch", [primary_ops = std::move(primary_ops), - is_notify_tag_closure, notify_tag, - this]() mutable { - return LogPollBatch( - notify_tag, - Seq(std::move(primary_ops), - [is_notify_tag_closure, notify_tag, this](StatusFlag r) { + call_handler_.SpawnInfallible( + "batch", [primary_ops = std::move(primary_ops), is_notify_tag_closure, + notify_tag, this]() mutable { + return LogPollBatch( + notify_tag, + Seq(std::move(primary_ops), [is_notify_tag_closure, notify_tag, + this](StatusFlag r) { return WaitForCqEndOp(is_notify_tag_closure, notify_tag, - StatusCast(r), cq()); + StatusCast(r), cq_); })); - }); + }); } } -RefCountedPtr MakeServerCall( - ClientMetadataHandle client_initial_metadata, ServerInterface* server, - Channel* channel, Arena* arena) { - return RefCountedPtr(arena->New( - std::move(client_initial_metadata), server, channel, arena)); +grpc_call* MakeServerCall(CallHandler call_handler, + ClientMetadataHandle client_initial_metadata, + ServerInterface* server, grpc_completion_queue* cq, + grpc_metadata_array* publish_initial_metadata) { + PublishMetadataArray(client_initial_metadata.get(), publish_initial_metadata, + false); + // TODO(ctiller): ideally we'd put this in the arena with the CallHandler, + // but there's an ownership problem: CallHandler owns the arena, and so would + // get destroyed before the base class Call destructor runs, leading to + // UB/crash. Investigate another path. + return (new ServerCall(std::move(client_initial_metadata), + std::move(call_handler), server, cq)) + ->c_ptr(); } -#else -RefCountedPtr MakeServerCall(ClientMetadataHandle, - ServerInterface*, Channel*, - Arena*) { - Crash("not implemented"); -} -#endif } // namespace grpc_core diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h index 9fb12f279e4..9388c142f67 100644 --- a/src/core/lib/surface/call.h +++ b/src/core/lib/surface/call.h @@ -82,7 +82,7 @@ class Call : public CppImplOf, public grpc_event_engine::experimental::EventEngine:: Closure /* for deadlines */ { public: - Arena* arena() { return arena_; } + virtual Arena* arena() = 0; bool is_client() const { return is_client_; } virtual void ContextSet(grpc_context_index elem, void* value, @@ -92,7 +92,7 @@ class Call : public CppImplOf, void CancelWithStatus(grpc_status_code status, const char* description); virtual void CancelWithError(grpc_error_handle error) = 0; virtual void SetCompletionQueue(grpc_completion_queue* cq) = 0; - char* GetPeer(); + virtual char* GetPeer() = 0; virtual grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag, bool is_notify_tag_closure) = 0; @@ -157,25 +157,15 @@ class Call : public CppImplOf, Call* sibling_prev = nullptr; }; - Call(Arena* arena, bool is_client, Timestamp send_deadline, - RefCountedPtr channel) - : channel_(std::move(channel)), - arena_(arena), - send_deadline_(send_deadline), - is_client_(is_client) { - DCHECK_NE(arena_, nullptr); - DCHECK(channel_ != nullptr); - } + Call(bool is_client, Timestamp send_deadline, + grpc_event_engine::experimental::EventEngine* event_engine) + : send_deadline_(send_deadline), + is_client_(is_client), + event_engine_(event_engine) {} ~Call() override = default; - void DeleteThis(); - ParentCall* GetOrCreateParentCall(); ParentCall* parent_call(); - Channel* channel() const { - DCHECK(channel_ != nullptr); - return channel_.get(); - } absl::Status InitParent(Call* parent, uint32_t propagation_mask); void PublishToParent(Call* parent); @@ -221,9 +211,9 @@ class Call : public CppImplOf, gpr_cycle_counter start_time() const { return start_time_; } + virtual grpc_compression_options compression_options() = 0; + private: - RefCountedPtr channel_; - Arena* const arena_; std::atomic parent_call_{nullptr}; ChildCall* child_ = nullptr; Timestamp send_deadline_; @@ -247,34 +237,13 @@ class Call : public CppImplOf, Timestamp deadline_ ABSL_GUARDED_BY(deadline_mu_) = Timestamp::InfFuture(); grpc_event_engine::experimental::EventEngine::TaskHandle ABSL_GUARDED_BY( deadline_mu_) deadline_task_; + grpc_event_engine::experimental::EventEngine* const event_engine_; gpr_cycle_counter start_time_ = gpr_get_cycle_counter(); }; class BasicPromiseBasedCall; class ServerPromiseBasedCall; -class ServerCallContext { - public: - virtual void PublishInitialMetadata( - ClientMetadataHandle metadata, - grpc_metadata_array* publish_initial_metadata) = 0; - - // Construct the top of the server call promise for the v2 filter stack. - // TODO(ctiller): delete when v3 is available. - virtual ArenaPromise MakeTopOfServerCallPromise( - CallArgs call_args, grpc_completion_queue* cq, - absl::FunctionRef publish) = 0; - - // Server stream data as supplied by the transport (so we can link the - // transport stream up with the call again). - // TODO(ctiller): legacy API - once we move transports to promises we'll - // create the promise directly and not need to pass around this token. - virtual const void* server_stream_data() = 0; - - protected: - ~ServerCallContext() = default; -}; - // TODO(ctiller): move more call things into this type class CallContext { public: @@ -300,8 +269,6 @@ class CallContext { gpr_atm* peer_string_atm_ptr(); gpr_cycle_counter call_start_time() { return start_time_; } - ServerCallContext* server_call_context(); - void set_traced(bool traced) { traced_ = traced; } bool traced() const { return traced_; } @@ -329,9 +296,10 @@ template <> struct ContextType {}; // TODO(ctiller): remove once call-v3 finalized -RefCountedPtr MakeServerCall( - ClientMetadataHandle client_initial_metadata, ServerInterface* server, - Channel* channel, Arena* arena); +grpc_call* MakeServerCall(CallHandler call_handler, + ClientMetadataHandle client_initial_metadata, + ServerInterface* server, grpc_completion_queue* cq, + grpc_metadata_array* publish_initial_metadata); } // namespace grpc_core diff --git a/src/core/lib/surface/channel_init.cc b/src/core/lib/surface/channel_init.cc index b94b189ffea..698a57b195d 100644 --- a/src/core/lib/surface/channel_init.cc +++ b/src/core/lib/surface/channel_init.cc @@ -104,9 +104,9 @@ ChannelInit::FilterRegistration::ExcludeFromMinimalStack() { ChannelInit::FilterRegistration& ChannelInit::Builder::RegisterFilter( grpc_channel_stack_type type, const grpc_channel_filter* filter, - const ChannelFilterVtable* vtable, SourceLocation registration_source) { + FilterAdder filter_adder, SourceLocation registration_source) { filters_[type].emplace_back(std::make_unique( - filter, vtable, registration_source)); + filter, filter_adder, registration_source)); return *filters_[type].back(); } @@ -223,9 +223,10 @@ ChannelInit::StackConfig ChannelInit::BuildStackConfig( while (!dependencies.empty()) { auto filter = take_ready_dependency(); auto* registration = filter_to_registration[filter]; - filters.emplace_back( - filter, registration->vtable_, std::move(registration->predicates_), - registration->skip_v3_, registration->registration_source_); + filters.emplace_back(filter, registration->filter_adder_, + std::move(registration->predicates_), + registration->skip_v3_, + registration->registration_source_); for (auto& p : dependencies) { p.second.erase(filter); } @@ -406,78 +407,21 @@ bool ChannelInit::CreateStack(ChannelStackBuilder* builder) const { return true; } -absl::StatusOr ChannelInit::CreateStackSegment( - grpc_channel_stack_type type, const ChannelArgs& args) const { +void ChannelInit::AddToInterceptionChainBuilder( + grpc_channel_stack_type type, InterceptionChainBuilder& builder) const { const auto& stack_config = stack_configs_[type]; - std::vector filters; - size_t channel_data_size = 0; - size_t channel_data_alignment = 0; // Based on predicates build a list of filters to include in this segment. for (const auto& filter : stack_config.filters) { if (filter.skip_v3) continue; - if (!filter.CheckPredicates(args)) continue; - if (filter.vtable == nullptr) { - return absl::InvalidArgumentError( + if (!filter.CheckPredicates(builder.channel_args())) continue; + if (filter.filter_adder == nullptr) { + builder.Fail(absl::InvalidArgumentError( absl::StrCat("Filter ", NameFromChannelFilter(filter.filter), - " has no v3-callstack vtable")); + " has no v3-callstack vtable"))); + return; } - channel_data_alignment = - std::max(channel_data_alignment, filter.vtable->alignment); - if (channel_data_size % filter.vtable->alignment != 0) { - channel_data_size += filter.vtable->alignment - - (channel_data_size % filter.vtable->alignment); - } - filters.push_back({channel_data_size, filter.vtable}); - channel_data_size += filter.vtable->size; - } - // Shortcut for empty segments. - if (filters.empty()) return StackSegment(); - // Allocate memory for the channel data, initialize channel filters into it. - uint8_t* p = static_cast( - gpr_malloc_aligned(channel_data_size, channel_data_alignment)); - for (size_t i = 0; i < filters.size(); i++) { - auto r = filters[i].vtable->init(p + filters[i].offset, args); - if (!r.ok()) { - for (size_t j = 0; j < i; j++) { - filters[j].vtable->destroy(p + filters[j].offset); - } - gpr_free_aligned(p); - return r; - } - } - return StackSegment(std::move(filters), p); -} - -/////////////////////////////////////////////////////////////////////////////// -// ChannelInit::StackSegment - -ChannelInit::StackSegment::StackSegment(std::vector filters, - uint8_t* channel_data) - : data_(MakeRefCounted(std::move(filters), channel_data)) {} - -void ChannelInit::StackSegment::AddToCallFilterStack( - CallFilters::StackBuilder& builder) { - if (data_ == nullptr) return; - data_->AddToCallFilterStack(builder); - builder.AddOwnedObject(data_); -}; - -ChannelInit::StackSegment::ChannelData::ChannelData( - std::vector filters, uint8_t* channel_data) - : filters_(std::move(filters)), channel_data_(channel_data) {} - -void ChannelInit::StackSegment::ChannelData::AddToCallFilterStack( - CallFilters::StackBuilder& builder) { - for (const auto& filter : filters_) { - filter.vtable->add_to_stack_builder(channel_data_ + filter.offset, builder); - } -} - -ChannelInit::StackSegment::ChannelData::~ChannelData() { - for (const auto& filter : filters_) { - filter.vtable->destroy(channel_data_ + filter.offset); + filter.filter_adder(builder); } - gpr_free_aligned(channel_data_); } } // namespace grpc_core diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index fcfef582994..c5067394014 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -38,6 +38,7 @@ #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/surface/channel_stack_type.h" #include "src/core/lib/transport/call_filters.h" +#include "src/core/lib/transport/interception_chain.h" /// This module provides a way for plugins (and the grpc core library itself) /// to register mutators for channel stacks. @@ -68,6 +69,8 @@ class ChannelInit { using InclusionPredicate = absl::AnyInvocable; // Post processor for the channel stack - applied in PostProcessorSlot order using PostProcessor = absl::AnyInvocable; + // Function that can be called to add a filter to a stack builder + using FilterAdder = void (*)(InterceptionChainBuilder&); // Post processing slots - up to one PostProcessor per slot can be registered // They run after filters registered are added to the channel stack builder, // but before Build is called - allowing ad-hoc mutation to the channel stack. @@ -77,25 +80,15 @@ class ChannelInit { kCount }; - // Vtable-like data structure for channel data initialization - struct ChannelFilterVtable { - size_t size; - size_t alignment; - absl::Status (*init)(void* data, const ChannelArgs& args); - void (*destroy)(void* data); - void (*add_to_stack_builder)(void* data, - CallFilters::StackBuilder& builder); - }; - class FilterRegistration { public: // TODO(ctiller): Remove grpc_channel_filter* arg when that can be // deprecated (once filter stack is removed). explicit FilterRegistration(const grpc_channel_filter* filter, - const ChannelFilterVtable* vtable, + FilterAdder filter_adder, SourceLocation registration_source) : filter_(filter), - vtable_(vtable), + filter_adder_(filter_adder), registration_source_(registration_source) {} FilterRegistration(const FilterRegistration&) = delete; FilterRegistration& operator=(const FilterRegistration&) = delete; @@ -170,7 +163,7 @@ class ChannelInit { private: friend class ChannelInit; const grpc_channel_filter* const filter_; - const ChannelFilterVtable* const vtable_; + const FilterAdder filter_adder_; std::vector after_; std::vector before_; std::vector predicates_; @@ -188,16 +181,17 @@ class ChannelInit { // properties of the filter being registered. // TODO(ctiller): remove in favor of the version that does not mention // grpc_channel_filter - FilterRegistration& RegisterFilter( - grpc_channel_stack_type type, const grpc_channel_filter* filter, - const ChannelFilterVtable* vtable = nullptr, - SourceLocation registration_source = {}); + FilterRegistration& RegisterFilter(grpc_channel_stack_type type, + const grpc_channel_filter* filter, + FilterAdder filter_adder = nullptr, + SourceLocation registration_source = {}); template FilterRegistration& RegisterFilter( grpc_channel_stack_type type, SourceLocation registration_source = {}) { - return RegisterFilter(type, &Filter::kFilter, - VtableForType::vtable(), - registration_source); + return RegisterFilter( + type, &Filter::kFilter, + [](InterceptionChainBuilder& builder) { builder.Add(); }, + registration_source); } // Filter does not participate in v3 @@ -232,58 +226,13 @@ class ChannelInit { [static_cast(PostProcessorSlot::kCount)]; }; - // A set of channel filters that can be added to a call stack. - // TODO(ctiller): move this out so it can be used independently of - // the global registration mechanisms. - class StackSegment final { - public: - // Registration of one channel filter in the stack. - struct ChannelFilter { - size_t offset; - const ChannelFilterVtable* vtable; - }; - - StackSegment() = default; - explicit StackSegment(std::vector filters, - uint8_t* channel_data); - StackSegment(const StackSegment& other) = delete; - StackSegment& operator=(const StackSegment& other) = delete; - StackSegment(StackSegment&& other) noexcept = default; - StackSegment& operator=(StackSegment&& other) = default; - - // Add this segment to a call filter stack builder - void AddToCallFilterStack(CallFilters::StackBuilder& builder); - - private: - // Combined channel data for the stack - class ChannelData : public RefCounted { - public: - explicit ChannelData(std::vector filters, - uint8_t* channel_data); - ~ChannelData() override; - - void AddToCallFilterStack(CallFilters::StackBuilder& builder); - - private: - std::vector filters_; - uint8_t* channel_data_; - }; - - RefCountedPtr data_; - }; - /// Construct a channel stack of some sort: see channel_stack.h for details /// \a builder is the channel stack builder to build into. GRPC_MUST_USE_RESULT bool CreateStack(ChannelStackBuilder* builder) const; - // Create a segment of a channel stack. - // Terminators and post processors are not included in this construction: - // terminators are a legacy filter-stack concept, and post processors - // need to migrate to other mechanisms. - // TODO(ctiller): figure out other mechanisms. - absl::StatusOr CreateStackSegment( - grpc_channel_stack_type type, const ChannelArgs& args) const; + void AddToInterceptionChainBuilder(grpc_channel_stack_type type, + InterceptionChainBuilder& builder) const; private: // The type of object returned by a filter's Create method. @@ -292,16 +241,16 @@ class ChannelInit { typename decltype(T::Create(ChannelArgs(), {}))::value_type; struct Filter { - Filter(const grpc_channel_filter* filter, const ChannelFilterVtable* vtable, + Filter(const grpc_channel_filter* filter, FilterAdder filter_adder, std::vector predicates, bool skip_v3, SourceLocation registration_source) : filter(filter), - vtable(vtable), + filter_adder(filter_adder), predicates(std::move(predicates)), registration_source(registration_source), skip_v3(skip_v3) {} const grpc_channel_filter* filter; - const ChannelFilterVtable* vtable; + const FilterAdder filter_adder; std::vector predicates; SourceLocation registration_source; bool skip_v3 = false; @@ -313,17 +262,6 @@ class ChannelInit { std::vector post_processors; }; - template - struct VtableForType { - static const ChannelFilterVtable* vtable() { return nullptr; } - }; - - template - struct VtableForType> { - static const ChannelFilterVtable kVtable; - static const ChannelFilterVtable* vtable() { return &kVtable; } - }; - StackConfig stack_configs_[GRPC_NUM_CHANNEL_STACK_TYPES]; static StackConfig BuildStackConfig( @@ -331,22 +269,6 @@ class ChannelInit { PostProcessor* post_processors, grpc_channel_stack_type type); }; -template -const ChannelInit::ChannelFilterVtable - ChannelInit::VtableForType>::kVtable = { - sizeof(CreatedType), alignof(CreatedType), - [](void* data, const ChannelArgs& args) -> absl::Status { - // TODO(ctiller): fill in ChannelFilter::Args (2nd arg) - absl::StatusOr> r = T::Create(args, {}); - if (!r.ok()) return r.status(); - new (data) CreatedType(std::move(*r)); - return absl::OkStatus(); - }, - [](void* data) { Destruct(static_cast*>(data)); }, - [](void* data, CallFilters::StackBuilder& builder) { - builder.Add(static_cast*>(data)->get()); - }}; - } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_SURFACE_CHANNEL_INIT_H diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc index 3ff4c77f062..b2a766ac8a0 100644 --- a/src/core/lib/surface/init.cc +++ b/src/core/lib/surface/init.cc @@ -66,10 +66,10 @@ static bool g_shutting_down ABSL_GUARDED_BY(g_init_mu) = false; namespace grpc_core { void RegisterSecurityFilters(CoreConfiguration::Builder* builder) { builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_SUBCHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_SUBCHANNEL) .IfHasChannelArg(GRPC_ARG_SECURITY_CONNECTOR); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_DIRECT_CHANNEL) .IfHasChannelArg(GRPC_ARG_SECURITY_CONNECTOR); builder->channel_init() ->RegisterFilter(GRPC_SERVER_CHANNEL) diff --git a/src/core/lib/transport/call_destination.h b/src/core/lib/transport/call_destination.h index 77683e230f5..938e0fd3725 100644 --- a/src/core/lib/transport/call_destination.h +++ b/src/core/lib/transport/call_destination.h @@ -51,6 +51,24 @@ class CallDestination : public DualRefCounted { virtual void HandleCall(CallHandler unstarted_call_handler) = 0; }; +template +auto MakeCallDestinationFromHandlerFunction(HC handle_call) { + class Impl : public CallDestination { + public: + explicit Impl(HC handle_call) : handle_call_(std::move(handle_call)) {} + + void Orphaned() override {} + + void HandleCall(CallHandler call_handler) override { + handle_call_(std::move(call_handler)); + } + + private: + HC handle_call_; + }; + return MakeRefCounted(std::move(handle_call)); +} + } // namespace grpc_core #endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_DESTINATION_H diff --git a/src/core/lib/transport/call_filters.h b/src/core/lib/transport/call_filters.h index a9e3a1c5b98..d637b6fb0de 100644 --- a/src/core/lib/transport/call_filters.h +++ b/src/core/lib/transport/call_filters.h @@ -1245,6 +1245,42 @@ const NoInterceptor template const NoInterceptor ServerTrailingMetadataInterceptor::Call::OnFinalize; +template +class ClientInitialMetadataInterceptor { + public: + class Call { + public: + auto OnClientInitialMetadata(ClientMetadata& md, + ClientInitialMetadataInterceptor* filter) { + return filter->fn_(md); + } + static const NoInterceptor OnServerInitialMetadata; + static const NoInterceptor OnClientToServerMessage; + static const NoInterceptor OnServerToClientMessage; + static const NoInterceptor OnServerTrailingMetadata; + static const NoInterceptor OnFinalize; + }; + + explicit ClientInitialMetadataInterceptor(Fn fn) : fn_(std::move(fn)) {} + + private: + GPR_NO_UNIQUE_ADDRESS Fn fn_; +}; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnServerInitialMetadata; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnClientToServerMessage; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnServerToClientMessage; +template +const NoInterceptor + ClientInitialMetadataInterceptor::Call::OnServerTrailingMetadata; +template +const NoInterceptor ClientInitialMetadataInterceptor::Call::OnFinalize; + } // namespace filters_detail // Execution environment for a stack of filters. @@ -1302,6 +1338,14 @@ class CallFilters { AddOwnedObject([](void* p) { delete static_cast(p); }, p.release()); } + template + void AddOnClientInitialMetadata(Fn fn) { + auto filter = std::make_unique< + filters_detail::ClientInitialMetadataInterceptor>(std::move(fn)); + Add(filter.get()); + AddOwnedObject(std::move(filter)); + } + template void AddOnServerTrailingMetadata(Fn fn) { auto filter = std::make_unique< diff --git a/src/core/lib/transport/call_spine.h b/src/core/lib/transport/call_spine.h index 8593e47e9c8..59c1fc2da16 100644 --- a/src/core/lib/transport/call_spine.h +++ b/src/core/lib/transport/call_spine.h @@ -518,6 +518,8 @@ class CallHandler { auto PullMessage() { return spine_->PullClientToServerMessage(); } + auto WasCancelled() { return spine_->WasCancelled(); } + template void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory, DebugLocation whence = {}) { @@ -536,11 +538,15 @@ class CallHandler { Arena* arena() { return spine_->arena(); } - grpc_event_engine::experimental::EventEngine* event_engine() { + grpc_event_engine::experimental::EventEngine* event_engine() const { return DownCast(spine_.get())->event_engine(); } // TODO(ctiller): re-evaluate this API + const grpc_call_context_element* legacy_context() const { + return DownCast(spine_.get())->legacy_context(); + } + grpc_call_context_element* legacy_context() { return DownCast(spine_.get())->legacy_context(); } diff --git a/src/core/lib/transport/interception_chain.h b/src/core/lib/transport/interception_chain.h index 5b05e481ff6..e9dcb937b19 100644 --- a/src/core/lib/transport/interception_chain.h +++ b/src/core/lib/transport/interception_chain.h @@ -175,12 +175,23 @@ class InterceptionChainBuilder final { return *this; }; + // Add a filter that just mutates client initial metadata. + template + void AddOnClientInitialMetadata(F f) { + stack_builder().AddOnClientInitialMetadata(std::move(f)); + } + // Add a filter that just mutates server trailing metadata. template void AddOnServerTrailingMetadata(F f) { stack_builder().AddOnServerTrailingMetadata(std::move(f)); } + void Fail(absl::Status status) { + CHECK(!status.ok()) << status; + if (status_.ok()) status_ = std::move(status); + } + // Build this stack absl::StatusOr> Build( FinalDestination final_destination); diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 65f57fdd475..5dbe2c6695f 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -55,6 +55,7 @@ #include "src/core/lib/promise/pipe.h" #include "src/core/lib/resource_quota/arena.h" #include "src/core/lib/slice/slice_buffer.h" +#include "src/core/lib/transport/call_destination.h" #include "src/core/lib/transport/call_final_info.h" #include "src/core/lib/transport/call_spine.h" #include "src/core/lib/transport/connectivity_state.h" @@ -481,6 +482,15 @@ typedef struct grpc_transport_op { grpc_handler_private_op_data handler_private; } grpc_transport_op; +// Allocate a grpc_transport_op, and preconfigure the on_complete closure to +// \a on_complete and then delete the returned transport op +grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete); +// Allocate a grpc_transport_stream_op_batch, and preconfigure the on_complete +// closure +// to \a on_complete and then delete the returned transport op +grpc_transport_stream_op_batch* grpc_make_transport_stream_op( + grpc_closure* on_complete); + void grpc_transport_stream_op_batch_finish_with_failure( grpc_transport_stream_op_batch* batch, grpc_error_handle error, grpc_core::CallCombiner* call_combiner); @@ -507,6 +517,21 @@ class Transport : public InternallyRefCounted { struct RawPointerChannelArgTag {}; static absl::string_view ChannelArgName() { return GRPC_ARG_TRANSPORT; } + // Though internally ref counted transports expose their "Ref" method to + // create a RefCountedPtr to themselves. The OrphanablePtr owner is the + // singleton decision maker on whether the transport should be destroyed or + // not. + // TODO(ctiller): consider moving to a DualRefCounted model (with the + // disadvantage that we would accidentally have many strong owners which is + // unnecessary for this type). + RefCountedPtr Ref() { + return InternallyRefCounted::Ref(); + } + template + RefCountedPtr RefAsSubclass() { + return InternallyRefCounted::RefAsSubclass(); + } + virtual FilterStackTransport* filter_stack_transport() = 0; virtual ClientTransport* client_transport() = 0; virtual ServerTransport* server_transport() = 0; @@ -527,6 +552,20 @@ class Transport : public InternallyRefCounted { // implementation of grpc_transport_perform_op virtual void PerformOp(grpc_transport_op* op) = 0; + void StartConnectivityWatch( + OrphanablePtr watcher) { + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->start_connectivity_watch = std::move(watcher); + PerformOp(op); + } + + void DisconnectWithError(grpc_error_handle error) { + CHECK(!error.ok()) << error; + grpc_transport_op* op = grpc_make_transport_op(nullptr); + op->disconnect_with_error = error; + PerformOp(op); + } + // implementation of grpc_transport_get_endpoint virtual grpc_endpoint* GetEndpoint() = 0; }; @@ -582,24 +621,9 @@ class ClientTransport : public Transport { class ServerTransport : public Transport { public: - // Acceptor helps transports create calls. - class Acceptor { - public: - // Returns an arena that can be used to allocate memory for initial metadata - // parsing, and later passed to CreateCall() as the underlying arena for - // that call. - virtual Arena* CreateArena() = 0; - // Create a call at the server (or fail) - // arena must have been previously allocated by CreateArena() - virtual absl::StatusOr CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) = 0; - - protected: - ~Acceptor() = default; - }; - // Called once slightly after transport setup to register the accept function. - virtual void SetAcceptor(Acceptor* acceptor) = 0; + virtual void SetCallDestination( + RefCountedPtr unstarted_call_handler) = 0; protected: ~ServerTransport() override = default; @@ -607,15 +631,6 @@ class ServerTransport : public Transport { } // namespace grpc_core -// Allocate a grpc_transport_op, and preconfigure the on_complete closure to -// \a on_complete and then delete the returned transport op -grpc_transport_op* grpc_make_transport_op(grpc_closure* on_complete); -// Allocate a grpc_transport_stream_op_batch, and preconfigure the on_complete -// closure -// to \a on_complete and then delete the returned transport op -grpc_transport_stream_op_batch* grpc_make_transport_stream_op( - grpc_closure* on_complete); - namespace grpc_core { // This is the key to be used for loading/storing keepalive_throttling in the // absl::Status object. diff --git a/src/core/load_balancing/pick_first/pick_first.cc b/src/core/load_balancing/pick_first/pick_first.cc index afcd49d547d..2307128507e 100644 --- a/src/core/load_balancing/pick_first/pick_first.cc +++ b/src/core/load_balancing/pick_first/pick_first.cc @@ -84,19 +84,25 @@ const auto kMetricDisconnections = "grpc.lb.pick_first.disconnections", "EXPERIMENTAL. Number of times the selected subchannel becomes " "disconnected.", - "{disconnection}", {kMetricLabelTarget}, {}, false); + "{disconnection}", false) + .Labels(kMetricLabelTarget) + .Build(); const auto kMetricConnectionAttemptsSucceeded = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.pick_first.connection_attempts_succeeded", "EXPERIMENTAL. Number of successful connection attempts.", "{attempt}", - {kMetricLabelTarget}, {}, false); + false) + .Labels(kMetricLabelTarget) + .Build(); const auto kMetricConnectionAttemptsFailed = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.pick_first.connection_attempts_failed", "EXPERIMENTAL. Number of failed connection attempts.", "{attempt}", - {kMetricLabelTarget}, {}, false); + false) + .Labels(kMetricLabelTarget) + .Build(); class PickFirstConfig final : public LoadBalancingPolicy::Config { public: diff --git a/src/core/load_balancing/rls/rls.cc b/src/core/load_balancing/rls/rls.cc index 3e9f08a5b9c..53480d6f091 100644 --- a/src/core/load_balancing/rls/rls.cc +++ b/src/core/load_balancing/rls/rls.cc @@ -128,26 +128,27 @@ constexpr absl::string_view kMetricLabelPickResult = "grpc.lb.pick_result"; const auto kMetricCacheSize = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( "grpc.lb.rls.cache_size", "EXPERIMENTAL. Size of the RLS cache.", "By", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricLabelRlsInstanceUuid}, - {}, false); + false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricLabelRlsInstanceUuid) + .Build(); const auto kMetricCacheEntries = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( "grpc.lb.rls.cache_entries", - "EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricLabelRlsInstanceUuid}, - {}, false); + "EXPERIMENTAL. Number of entries in the RLS cache.", "{entry}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricLabelRlsInstanceUuid) + .Build(); const auto kMetricDefaultTargetPicks = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.rls.default_target_picks", "EXPERIMENTAL. Number of LB picks sent to the default target.", - "{pick}", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricRlsDataPlaneTarget, kMetricLabelPickResult}, - {}, false); + "{pick}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricRlsDataPlaneTarget, kMetricLabelPickResult) + .Build(); const auto kMetricTargetPicks = GlobalInstrumentsRegistry::RegisterUInt64Counter( @@ -156,17 +157,19 @@ const auto kMetricTargetPicks = "if the default target is also returned by the RLS server, RPCs sent " "to that target from the cache will be counted in this metric, not " "in grpc.rls.default_target_picks.", - "{pick}", - {kMetricLabelTarget, kMetricLabelRlsServerTarget, - kMetricRlsDataPlaneTarget, kMetricLabelPickResult}, - {}, false); + "{pick}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget, + kMetricRlsDataPlaneTarget, kMetricLabelPickResult) + .Build(); const auto kMetricFailedPicks = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.rls.failed_picks", "EXPERIMENTAL. Number of LB picks failed due to either a failed RLS " "request or the RLS channel being throttled.", - "{pick}", {kMetricLabelTarget, kMetricLabelRlsServerTarget}, {}, false); + "{pick}", false) + .Labels(kMetricLabelTarget, kMetricLabelRlsServerTarget) + .Build(); constexpr absl::string_view kRls = "rls_experimental"; const char kGrpc[] = "grpc"; @@ -754,9 +757,9 @@ class RlsLb final : public LoadBalancingPolicy { // Updates the picker in the work serializer. void UpdatePickerLocked() ABSL_LOCKS_EXCLUDED(&mu_); - void MaybeExportPickCount( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - absl::string_view target, const PickResult& pick_result); + template + void MaybeExportPickCount(HandleType handle, absl::string_view target, + const PickResult& pick_result); const std::string instance_uuid_; @@ -1961,7 +1964,7 @@ RlsLb::RlsLb(Args args) MutexLock lock(&mu_); cache_.ReportMetricsLocked(reporter); }, - {kMetricCacheSize, kMetricCacheEntries})) { + Duration::Seconds(5), kMetricCacheSize, kMetricCacheEntries)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_rls_trace)) { gpr_log(GPR_INFO, "[rlslb %p] policy created", this); } @@ -2230,9 +2233,9 @@ void RlsLb::UpdatePickerLocked() { MakeRefCounted(RefAsSubclass(DEBUG_LOCATION, "Picker"))); } -void RlsLb::MaybeExportPickCount( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - absl::string_view target, const PickResult& pick_result) { +template +void RlsLb::MaybeExportPickCount(HandleType handle, absl::string_view target, + const PickResult& pick_result) { absl::string_view pick_result_string = Match( pick_result.result, [](const LoadBalancingPolicy::PickResult::Complete&) { diff --git a/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc b/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc index bf174c55a56..d0a4165f393 100644 --- a/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +++ b/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc @@ -85,12 +85,16 @@ constexpr absl::string_view kWeightedRoundRobin = "weighted_round_robin"; constexpr absl::string_view kMetricLabelLocality = "grpc.lb.locality"; -const auto kMetricRrFallback = GlobalInstrumentsRegistry::RegisterUInt64Counter( - "grpc.lb.wrr.rr_fallback", - "EXPERIMENTAL. Number of scheduler updates in which there were not " - "enough endpoints with valid weight, which caused the WRR policy to " - "fall back to RR behavior.", - "{update}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); +const auto kMetricRrFallback = + GlobalInstrumentsRegistry::RegisterUInt64Counter( + "grpc.lb.wrr.rr_fallback", + "EXPERIMENTAL. Number of scheduler updates in which there were not " + "enough endpoints with valid weight, which caused the WRR policy to " + "fall back to RR behavior.", + "{update}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); const auto kMetricEndpointWeightNotYetUsable = GlobalInstrumentsRegistry::RegisterUInt64Counter( @@ -99,14 +103,20 @@ const auto kMetricEndpointWeightNotYetUsable = "don't yet have usable weight information (i.e., either the load " "report has not yet been received, or it is within the blackout " "period).", - "{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); + "{endpoint}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); const auto kMetricEndpointWeightStale = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.lb.wrr.endpoint_weight_stale", "EXPERIMENTAL. Number of endpoints from each scheduler update whose " "latest weight is older than the expiration period.", - "{endpoint}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); + "{endpoint}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); const auto kMetricEndpointWeights = GlobalInstrumentsRegistry::RegisterDoubleHistogram( @@ -115,7 +125,10 @@ const auto kMetricEndpointWeights = "Each bucket will be a counter that is incremented once for every " "endpoint whose weight is within that range. Note that endpoints " "without usable weights will have weight 0.", - "{weight}", {kMetricLabelTarget}, {kMetricLabelLocality}, false); + "{weight}", false) + .Labels(kMetricLabelTarget) + .OptionalLabels(kMetricLabelLocality) + .Build(); // Config for WRR policy. class WeightedRoundRobinConfig final : public LoadBalancingPolicy::Config { diff --git a/src/core/load_balancing/xds/xds_override_host.cc b/src/core/load_balancing/xds/xds_override_host.cc index c8821ca0a91..41b3eb36ef6 100644 --- a/src/core/load_balancing/xds/xds_override_host.cc +++ b/src/core/load_balancing/xds/xds_override_host.cc @@ -32,6 +32,7 @@ #include "absl/base/thread_annotations.h" #include "absl/functional/function_ref.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" @@ -530,7 +531,7 @@ XdsOverrideHostLb::Picker::PickOverridenHost( // a connection attempt and queue the pick until that attempt completes. if (idle_subchannel != nullptr) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { - gpr_log(GPR_INFO, "Picker override found IDLE subchannel"); + LOG(INFO) << "Picker override found IDLE subchannel"; } // Deletes itself after the connection is requested. new SubchannelConnectionRequester(std::move(idle_subchannel)); @@ -540,7 +541,7 @@ XdsOverrideHostLb::Picker::PickOverridenHost( // queue the pick and wait for the connection attempt to complete. if (found_connecting) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { - gpr_log(GPR_INFO, "Picker override found CONNECTING subchannel"); + LOG(INFO) << "Picker override found CONNECTING subchannel"; } return PickResult::Queue(); } @@ -549,7 +550,7 @@ XdsOverrideHostLb::Picker::PickOverridenHost( // creation of a subchannel for that entry. if (!address_with_no_subchannel.empty()) { if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) { - gpr_log(GPR_INFO, "Picker override found entry with no subchannel"); + LOG(INFO) << "Picker override found entry with no subchannel"; } if (!IsWorkSerializerDispatchEnabled()) { new SubchannelCreationRequester(policy_, address_with_no_subchannel); diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc index c0205fa8497..80b4010593e 100644 --- a/src/core/plugin_registry/grpc_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_plugin_registry.cc @@ -79,10 +79,11 @@ namespace { void RegisterBuiltins(CoreConfiguration::Builder* builder) { RegisterServerCallTracerFilter(builder); builder->channel_init() - ->RegisterFilter(GRPC_CLIENT_LAME_CHANNEL) + ->RegisterV2Filter(GRPC_CLIENT_LAME_CHANNEL) .Terminal(); builder->channel_init() ->RegisterFilter(GRPC_SERVER_CHANNEL, &Server::kServerTopFilter) + .SkipV3() .BeforeAll(); } diff --git a/src/core/server/server.cc b/src/core/server/server.cc index 04d0f52da3e..40c87eda174 100644 --- a/src/core/server/server.cc +++ b/src/core/server/server.cc @@ -57,6 +57,7 @@ #include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/mpscq.h" +#include "src/core/lib/gprpp/orphanable.h" #include "src/core/lib/gprpp/status_helper.h" #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/pollset_set.h" @@ -81,6 +82,7 @@ #include "src/core/lib/surface/wait_for_cq_end_op.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/interception_chain.h" namespace grpc_core { @@ -235,7 +237,8 @@ struct Server::RequestedCall { template void Complete(OptionalPayload payload, ClientMetadata& md) { - Timestamp deadline = GetContext()->deadline(); + Timestamp deadline = + md.get(GrpcTimeoutMetadata()).value_or(Timestamp::InfFuture()); switch (type) { case RequestedCall::Type::BATCH_CALL: CHECK(!payload.has_value()); @@ -288,23 +291,29 @@ struct Server::RequestedCall { // application to explicitly request RPCs and then matching those to incoming // RPCs, along with a slow path by which incoming RPCs are put on a locked // pending list if they aren't able to be matched to an application request. -class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { +class Server::RealRequestMatcher : public RequestMatcherInterface { public: - explicit RealRequestMatcherFilterStack(Server* server) + explicit RealRequestMatcher(Server* server) : server_(server), requests_per_cq_(server->cqs_.size()) {} - ~RealRequestMatcherFilterStack() override { + ~RealRequestMatcher() override { for (LockedMultiProducerSingleConsumerQueue& queue : requests_per_cq_) { CHECK_EQ(queue.Pop(), nullptr); } - CHECK(pending_.empty()); + CHECK(pending_filter_stack_.empty()); + CHECK(pending_promises_.empty()); } void ZombifyPending() override { - while (!pending_.empty()) { - pending_.front().calld->SetState(CallData::CallState::ZOMBIED); - pending_.front().calld->KillZombie(); - pending_.pop(); + while (!pending_filter_stack_.empty()) { + pending_filter_stack_.front().calld->SetState( + CallData::CallState::ZOMBIED); + pending_filter_stack_.front().calld->KillZombie(); + pending_filter_stack_.pop(); + } + while (!pending_promises_.empty()) { + pending_promises_.front()->Finish(absl::InternalError("Server closed")); + pending_promises_.pop(); } } @@ -329,35 +338,56 @@ class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { // matching calls struct NextPendingCall { RequestedCall* rc = nullptr; - CallData* pending; + CallData* pending_filter_stack = nullptr; + PendingCallPromises pending_promise; }; while (true) { NextPendingCall pending_call; { MutexLock lock(&server_->mu_call_); - while (!pending_.empty() && - pending_.front().Age() > server_->max_time_in_pending_queue_) { - pending_.front().calld->SetState(CallData::CallState::ZOMBIED); - pending_.front().calld->KillZombie(); - pending_.pop(); + while (!pending_filter_stack_.empty() && + pending_filter_stack_.front().Age() > + server_->max_time_in_pending_queue_) { + pending_filter_stack_.front().calld->SetState( + CallData::CallState::ZOMBIED); + pending_filter_stack_.front().calld->KillZombie(); + pending_filter_stack_.pop(); } - if (!pending_.empty()) { + if (!pending_promises_.empty()) { pending_call.rc = reinterpret_cast( requests_per_cq_[request_queue_index].Pop()); if (pending_call.rc != nullptr) { - pending_call.pending = pending_.front().calld; - pending_.pop(); + pending_call.pending_promise = + std::move(pending_promises_.front()); + pending_promises_.pop(); + } + } else if (!pending_filter_stack_.empty()) { + pending_call.rc = reinterpret_cast( + requests_per_cq_[request_queue_index].Pop()); + if (pending_call.rc != nullptr) { + pending_call.pending_filter_stack = + pending_filter_stack_.front().calld; + pending_filter_stack_.pop(); } } } if (pending_call.rc == nullptr) break; - if (!pending_call.pending->MaybeActivate()) { - // Zombied Call - pending_call.pending->KillZombie(); - requests_per_cq_[request_queue_index].Push( - &pending_call.rc->mpscq_node); + if (pending_call.pending_filter_stack != nullptr) { + if (!pending_call.pending_filter_stack->MaybeActivate()) { + // Zombied Call + pending_call.pending_filter_stack->KillZombie(); + requests_per_cq_[request_queue_index].Push( + &pending_call.rc->mpscq_node); + } else { + pending_call.pending_filter_stack->Publish(request_queue_index, + pending_call.rc); + } } else { - pending_call.pending->Publish(request_queue_index, pending_call.rc); + if (!pending_call.pending_promise->Finish( + server(), request_queue_index, pending_call.rc)) { + requests_per_cq_[request_queue_index].Push( + &pending_call.rc->mpscq_node); + } } } } @@ -395,7 +425,7 @@ class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { } if (rc == nullptr) { calld->SetState(CallData::CallState::PENDING); - pending_.push(PendingCall{calld}); + pending_filter_stack_.push(PendingCallFilterStack{calld}); return; } } @@ -403,91 +433,6 @@ class Server::RealRequestMatcherFilterStack : public RequestMatcherInterface { calld->Publish(cq_idx, rc); } - ArenaPromise> MatchRequest(size_t) override { - Crash("not implemented for filter stack request matcher"); - } - - Server* server() const final { return server_; } - - private: - Server* const server_; - struct PendingCall { - CallData* calld; - Timestamp created = Timestamp::Now(); - Duration Age() { return Timestamp::Now() - created; } - }; - std::queue pending_; - std::vector requests_per_cq_; -}; - -class Server::RealRequestMatcherPromises : public RequestMatcherInterface { - public: - explicit RealRequestMatcherPromises(Server* server) - : server_(server), requests_per_cq_(server->cqs_.size()) {} - - ~RealRequestMatcherPromises() override { - for (LockedMultiProducerSingleConsumerQueue& queue : requests_per_cq_) { - CHECK_EQ(queue.Pop(), nullptr); - } - } - - void ZombifyPending() override { - while (!pending_.empty()) { - pending_.front()->Finish(absl::InternalError("Server closed")); - pending_.pop(); - } - } - - void KillRequests(grpc_error_handle error) override { - for (size_t i = 0; i < requests_per_cq_.size(); i++) { - RequestedCall* rc; - while ((rc = reinterpret_cast( - requests_per_cq_[i].Pop())) != nullptr) { - server_->FailCall(i, rc, error); - } - } - } - - size_t request_queue_count() const override { - return requests_per_cq_.size(); - } - - void RequestCallWithPossiblePublish(size_t request_queue_index, - RequestedCall* call) override { - if (requests_per_cq_[request_queue_index].Push(&call->mpscq_node)) { - // this was the first queued request: we need to lock and start - // matching calls - struct NextPendingCall { - RequestedCall* rc = nullptr; - PendingCall pending; - }; - while (true) { - NextPendingCall pending_call; - { - MutexLock lock(&server_->mu_call_); - if (!pending_.empty()) { - pending_call.rc = reinterpret_cast( - requests_per_cq_[request_queue_index].Pop()); - if (pending_call.rc != nullptr) { - pending_call.pending = std::move(pending_.front()); - pending_.pop(); - } - } - } - if (pending_call.rc == nullptr) break; - if (!pending_call.pending->Finish(server(), request_queue_index, - pending_call.rc)) { - requests_per_cq_[request_queue_index].Push( - &pending_call.rc->mpscq_node); - } - } - } - } - - void MatchOrQueue(size_t, CallData*) override { - Crash("not implemented for promises"); - } - ArenaPromise> MatchRequest( size_t start_request_queue_index) override { for (size_t i = 0; i < requests_per_cq_.size(); i++) { @@ -509,10 +454,11 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { { std::vector> removed_pending; MutexLock lock(&server_->mu_call_); - while (!pending_.empty() && - pending_.front()->Age() > server_->max_time_in_pending_queue_) { - removed_pending.push_back(std::move(pending_.front())); - pending_.pop(); + while (!pending_promises_.empty() && + pending_promises_.front()->Age() > + server_->max_time_in_pending_queue_) { + removed_pending.push_back(std::move(pending_promises_.front())); + pending_promises_.pop(); } for (loop_count = 0; loop_count < requests_per_cq_.size(); loop_count++) { cq_idx = @@ -521,14 +467,14 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { if (rc != nullptr) break; } if (rc == nullptr) { - if (server_->pending_backlog_protector_.Reject(pending_.size(), + if (server_->pending_backlog_protector_.Reject(pending_promises_.size(), server_->bitgen_)) { return Immediate(absl::ResourceExhaustedError( "Too many pending requests for this server")); } auto w = std::make_shared( GetContext()->MakeOwningWaker()); - pending_.push(w); + pending_promises_.push(w); return OnCancel( [w]() -> Poll> { std::unique_ptr> r( @@ -546,6 +492,11 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { private: Server* const server_; + struct PendingCallFilterStack { + CallData* calld; + Timestamp created = Timestamp::Now(); + Duration Age() { return Timestamp::Now() - created; } + }; struct ActivityWaiter { using ResultType = absl::StatusOr; explicit ActivityWaiter(Waker waker) : waker(std::move(waker)) {} @@ -580,8 +531,9 @@ class Server::RealRequestMatcherPromises : public RequestMatcherInterface { std::atomic result{nullptr}; const Timestamp created = Timestamp::Now(); }; - using PendingCall = std::shared_ptr; - std::queue pending_; + using PendingCallPromises = std::shared_ptr; + std::queue pending_filter_stack_; + std::queue pending_promises_; std::vector requests_per_cq_; }; @@ -784,13 +736,40 @@ class ChannelBroadcaster { } // namespace +// +// Server::TransportConnectivityWatcher +// + +class Server::TransportConnectivityWatcher + : public AsyncConnectivityStateWatcherInterface { + public: + TransportConnectivityWatcher(RefCountedPtr transport, + RefCountedPtr server) + : transport_(std::move(transport)), server_(std::move(server)) {} + + private: + void OnConnectivityStateChange(grpc_connectivity_state new_state, + const absl::Status& /*status*/) override { + // Don't do anything until we are being shut down. + if (new_state != GRPC_CHANNEL_SHUTDOWN) return; + // Shut down channel. + MutexLock lock(&server_->mu_global_); + server_->connections_.erase(transport_.get()); + --server_->connections_open_; + server_->MaybeFinishShutdown(); + } + + RefCountedPtr transport_; + RefCountedPtr server_; +}; + // // Server // const grpc_channel_filter Server::kServerTopFilter = { Server::CallData::StartTransportStreamOpBatch, - Server::ChannelData::MakeCallPromise, + nullptr, [](grpc_channel_element*, CallSpineInterface*) { // TODO(ctiller): remove the server filter when call-v3 is finalized }, @@ -826,12 +805,91 @@ RefCountedPtr CreateChannelzNode( return channelz_node; } +absl::StatusOr CheckClientMetadata( + ValueOrFailure md) { + if (!md.ok()) { + return absl::InternalError("Missing metadata"); + } + if (!md.value()->get_pointer(HttpPathMetadata())) { + return absl::InternalError("Missing :path header"); + } + if (!md.value()->get_pointer(HttpAuthorityMetadata())) { + return absl::InternalError("Missing :authority header"); + } + return std::move(*md); +} } // namespace +auto Server::MatchAndPublishCall(CallHandler call_handler) { + call_handler.SpawnGuarded("request_matcher", [this, call_handler]() mutable { + return TrySeq( + // Wait for initial metadata to pass through all filters + Map(call_handler.PullClientInitialMetadata(), CheckClientMetadata), + // Match request with requested call + [this, call_handler](ClientMetadataHandle md) mutable { + auto* registered_method = static_cast( + md->get(GrpcRegisteredMethod()).value_or(nullptr)); + RequestMatcherInterface* rm; + grpc_server_register_method_payload_handling payload_handling = + GRPC_SRM_PAYLOAD_NONE; + if (registered_method == nullptr) { + rm = unregistered_request_matcher_.get(); + } else { + payload_handling = registered_method->payload_handling; + rm = registered_method->matcher.get(); + } + auto maybe_read_first_message = If( + payload_handling == GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, + [call_handler]() mutable { return call_handler.PullMessage(); }, + []() -> ValueOrFailure> { + return ValueOrFailure>( + absl::nullopt); + }); + return TryJoin( + std::move(maybe_read_first_message), rm->MatchRequest(0), + [md = std::move(md)]() mutable { + return ValueOrFailure(std::move(md)); + }); + }, + // Publish call to cq + [call_handler, this](std::tuple, + RequestMatcherInterface::MatchResult, + ClientMetadataHandle> + r) { + RequestMatcherInterface::MatchResult& mr = std::get<1>(r); + auto md = std::move(std::get<2>(r)); + auto* rc = mr.TakeCall(); + rc->Complete(std::move(std::get<0>(r)), *md); + grpc_call* call = + MakeServerCall(call_handler, std::move(md), this, + rc->cq_bound_to_call, rc->initial_metadata); + *rc->call = call; + return Map(WaitForCqEndOp(false, rc->tag, absl::OkStatus(), mr.cq()), + [rc = std::unique_ptr(rc)](Empty) { + return absl::OkStatus(); + }); + }); + }); +} + +absl::StatusOr> +Server::MakeCallDestination(const ChannelArgs& args) { + InterceptionChainBuilder builder(args); + builder.AddOnClientInitialMetadata( + [this](ClientMetadata& md) { SetRegisteredMethodOnMetadata(md); }); + CoreConfiguration::Get().channel_init().AddToInterceptionChainBuilder( + GRPC_SERVER_CHANNEL, builder); + return builder.Build( + MakeCallDestinationFromHandlerFunction([this](CallHandler handler) { + return MatchAndPublishCall(std::move(handler)); + })); +} + Server::Server(const ChannelArgs& args) : channel_args_(args), channelz_node_(CreateChannelzNode(args)), server_call_tracer_factory_(ServerCallTracerFactory::Get(args)), + compression_options_(CompressionOptionsFromChannelArgs(args)), max_time_in_pending_queue_(Duration::Seconds( channel_args_ .GetInt(GRPC_ARG_SERVER_MAX_UNREQUESTED_TIME_IN_SERVER_SECONDS) @@ -862,15 +920,6 @@ void Server::AddListener(OrphanablePtr listener) { } void Server::Start() { - auto make_real_request_matcher = - [this]() -> std::unique_ptr { - if (IsPromiseBasedServerCallEnabled()) { - return std::make_unique(this); - } else { - return std::make_unique(this); - } - }; - started_ = true; for (grpc_completion_queue* cq : cqs_) { if (grpc_cq_can_listen(cq)) { @@ -878,11 +927,11 @@ void Server::Start() { } } if (unregistered_request_matcher_ == nullptr) { - unregistered_request_matcher_ = make_real_request_matcher(); + unregistered_request_matcher_ = std::make_unique(this); } for (auto& rm : registered_methods_) { if (rm.second->matcher == nullptr) { - rm.second->matcher = make_real_request_matcher(); + rm.second->matcher = std::make_unique(this); } } { @@ -913,37 +962,61 @@ grpc_error_handle Server::SetupTransport( const RefCountedPtr& socket_node) { // Create channel. global_stats().IncrementServerChannelsCreated(); - absl::StatusOr> channel = - LegacyChannel::Create("", args.SetObject(transport), GRPC_SERVER_CHANNEL); - if (!channel.ok()) { - return absl_status_to_grpc_error(channel.status()); - } - ChannelData* chand = static_cast( - grpc_channel_stack_element((*channel)->channel_stack(), 0)->channel_data); - // Set up CQs. - size_t cq_idx; - for (cq_idx = 0; cq_idx < cqs_.size(); cq_idx++) { - if (grpc_cq_pollset(cqs_[cq_idx]) == accepting_pollset) break; - } - if (cq_idx == cqs_.size()) { - // Completion queue not found. Pick a random one to publish new calls to. - cq_idx = static_cast(rand()) % std::max(1, cqs_.size()); - } // Set up channelz node. - intptr_t channelz_socket_uuid = 0; - if (socket_node != nullptr) { - channelz_socket_uuid = socket_node->uuid(); - channelz_node_->AddChildSocket(socket_node); - } - // Initialize chand. - chand->InitTransport(Ref(), std::move(*channel), cq_idx, transport, - channelz_socket_uuid); + if (transport->server_transport() != nullptr) { + // Take ownership + // TODO(ctiller): post-v3-transition make this method take an + // OrphanablePtr directly. + OrphanablePtr t(transport->server_transport()); + auto destination = MakeCallDestination(args.SetObject(transport)); + if (!destination.ok()) { + return absl_status_to_grpc_error(destination.status()); + } + // TODO(ctiller): add channelz node + t->SetCallDestination(std::move(*destination)); + MutexLock lock(&mu_global_); + if (ShutdownCalled()) { + t->DisconnectWithError(GRPC_ERROR_CREATE("Server shutdown")); + } + t->StartConnectivityWatch(MakeOrphanable( + t->RefAsSubclass(), Ref())); + gpr_log(GPR_INFO, "Adding connection"); + connections_.emplace(std::move(t)); + ++connections_open_; + } else { + CHECK(transport->filter_stack_transport() != nullptr); + absl::StatusOr> channel = LegacyChannel::Create( + "", args.SetObject(transport), GRPC_SERVER_CHANNEL); + if (!channel.ok()) { + return absl_status_to_grpc_error(channel.status()); + } + ChannelData* chand = static_cast( + grpc_channel_stack_element((*channel)->channel_stack(), 0) + ->channel_data); + // Set up CQs. + size_t cq_idx; + for (cq_idx = 0; cq_idx < cqs_.size(); cq_idx++) { + if (grpc_cq_pollset(cqs_[cq_idx]) == accepting_pollset) break; + } + if (cq_idx == cqs_.size()) { + // Completion queue not found. Pick a random one to publish new calls to. + cq_idx = static_cast(rand()) % std::max(1, cqs_.size()); + } + intptr_t channelz_socket_uuid = 0; + if (socket_node != nullptr) { + channelz_socket_uuid = socket_node->uuid(); + channelz_node_->AddChildSocket(socket_node); + } + // Initialize chand. + chand->InitTransport(Ref(), std::move(*channel), cq_idx, transport, + channelz_socket_uuid); + } return absl::OkStatus(); } bool Server::HasOpenConnections() { MutexLock lock(&mu_global_); - return !channels_.empty(); + return !channels_.empty() || !connections_.empty(); } void Server::SetRegisteredMethodAllocator( @@ -1023,16 +1096,18 @@ void Server::MaybeFinishShutdown() { MutexLock lock(&mu_call_); KillPendingWorkLocked(GRPC_ERROR_CREATE("Server Shutdown")); } - if (!channels_.empty() || listeners_destroyed_ < listeners_.size()) { + if (!channels_.empty() || connections_open_ > 0 || + listeners_destroyed_ < listeners_.size()) { if (gpr_time_cmp(gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), last_shutdown_message_time_), gpr_time_from_seconds(1, GPR_TIMESPAN)) >= 0) { last_shutdown_message_time_ = gpr_now(GPR_CLOCK_REALTIME); gpr_log(GPR_DEBUG, - "Waiting for %" PRIuPTR " channels and %" PRIuPTR "/%" PRIuPTR + "Waiting for %" PRIuPTR " channels %" PRIuPTR + " connections and %" PRIuPTR "/%" PRIuPTR " listeners to be destroyed before shutting down server", - channels_.size(), listeners_.size() - listeners_destroyed_, - listeners_.size()); + channels_.size(), connections_open_, + listeners_.size() - listeners_destroyed_, listeners_.size()); } return; } @@ -1095,6 +1170,7 @@ void DonePublishedShutdown(void* /*done_arg*/, grpc_cq_completion* storage) { // -- Once there are no more calls in progress, the channel is closed. void Server::ShutdownAndNotify(grpc_completion_queue* cq, void* tag) { ChannelBroadcaster broadcaster; + absl::flat_hash_set> removing_connections; { // Wait for startup to be finished. Locks mu_global. MutexLock lock(&mu_global_); @@ -1114,6 +1190,7 @@ void Server::ShutdownAndNotify(grpc_completion_queue* cq, void* tag) { } last_shutdown_message_time_ = gpr_now(GPR_CLOCK_REALTIME); broadcaster.FillChannelsLocked(GetChannelsLocked()); + removing_connections.swap(connections_); // Collect all unregistered then registered calls. { MutexLock lock(&mu_call_); @@ -1300,17 +1377,6 @@ Server::ChannelData::~ChannelData() { } } -Arena* Server::ChannelData::CreateArena() { return channel_->CreateArena(); } - -absl::StatusOr Server::ChannelData::CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) { - SetRegisteredMethodOnMetadata(*client_initial_metadata); - auto call = MakeServerCall(std::move(client_initial_metadata), server_.get(), - channel_.get(), arena); - InitCall(call); - return CallInitiator(std::move(call)); -} - void Server::ChannelData::InitTransport(RefCountedPtr server, OrphanablePtr channel, size_t cq_idx, Transport* transport, @@ -1327,22 +1393,15 @@ void Server::ChannelData::InitTransport(RefCountedPtr server, } // Start accept_stream transport op. grpc_transport_op* op = grpc_make_transport_op(nullptr); - int accept_stream_types = 0; - if (transport->filter_stack_transport() != nullptr) { - ++accept_stream_types; - op->set_accept_stream = true; - op->set_accept_stream_fn = AcceptStream; - op->set_registered_method_matcher_fn = [](void* arg, - ClientMetadata* metadata) { - static_cast(arg)->SetRegisteredMethodOnMetadata(*metadata); - }; - op->set_accept_stream_user_data = this; - } - if (transport->server_transport() != nullptr) { - ++accept_stream_types; - transport->server_transport()->SetAcceptor(this); - } - CHECK_EQ(accept_stream_types, 1); + CHECK(transport->filter_stack_transport() != nullptr); + op->set_accept_stream = true; + op->set_accept_stream_fn = AcceptStream; + op->set_registered_method_matcher_fn = [](void* arg, + ClientMetadata* metadata) { + static_cast(arg)->server_->SetRegisteredMethodOnMetadata( + *metadata); + }; + op->set_accept_stream_user_data = this; op->start_connectivity_watch = MakeOrphanable(this); if (server_->ShutdownCalled()) { op->disconnect_with_error = GRPC_ERROR_CREATE("Server shutdown"); @@ -1350,24 +1409,23 @@ void Server::ChannelData::InitTransport(RefCountedPtr server, transport->PerformOp(op); } -Server::RegisteredMethod* Server::ChannelData::GetRegisteredMethod( +Server::RegisteredMethod* Server::GetRegisteredMethod( const absl::string_view& host, const absl::string_view& path) { - if (server_->registered_methods_.empty()) return nullptr; + if (registered_methods_.empty()) return nullptr; // check for an exact match with host - auto it = server_->registered_methods_.find(std::make_pair(host, path)); - if (it != server_->registered_methods_.end()) { + auto it = registered_methods_.find(std::make_pair(host, path)); + if (it != registered_methods_.end()) { return it->second.get(); } // check for wildcard method definition (no host set) - it = server_->registered_methods_.find(std::make_pair("", path)); - if (it != server_->registered_methods_.end()) { + it = registered_methods_.find(std::make_pair("", path)); + if (it != registered_methods_.end()) { return it->second.get(); } return nullptr; } -void Server::ChannelData::SetRegisteredMethodOnMetadata( - ClientMetadata& metadata) { +void Server::SetRegisteredMethodOnMetadata(ClientMetadata& metadata) { auto* authority = metadata.get_pointer(HttpAuthorityMetadata()); if (authority == nullptr) { authority = metadata.get_pointer(HostMetadata()); @@ -1403,188 +1461,14 @@ void Server::ChannelData::AcceptStream(void* arg, Transport* /*transport*/, grpc_call* call; grpc_error_handle error = grpc_call_create(&args, &call); grpc_call_stack* call_stack = grpc_call_get_call_stack(call); - if (call_stack == nullptr) { // Promise based calls do not have a call stack - CHECK(error.ok()); - CHECK(IsPromiseBasedServerCallEnabled()); + CHECK_NE(call_stack, nullptr); + grpc_call_element* elem = grpc_call_stack_element(call_stack, 0); + auto* calld = static_cast(elem->call_data); + if (!error.ok()) { + calld->FailCallCreation(); return; - } else { - grpc_call_element* elem = grpc_call_stack_element(call_stack, 0); - auto* calld = static_cast(elem->call_data); - if (!error.ok()) { - calld->FailCallCreation(); - return; - } - calld->Start(elem); } -} - -namespace { -auto CancelledDueToServerShutdown() { - return [] { - return ServerMetadataFromStatus(absl::CancelledError("Server shutdown")); - }; -} -} // namespace - -void Server::ChannelData::InitCall(RefCountedPtr call) { - call->SpawnGuarded("request_matcher", [this, call]() { - return TrySeq( - // Wait for initial metadata to pass through all filters - Map(call->PullClientInitialMetadata(), - [](ValueOrFailure md) - -> absl::StatusOr { - if (!md.ok()) { - return absl::InternalError("Missing metadata"); - } - if (!md.value()->get_pointer(HttpPathMetadata())) { - return absl::InternalError("Missing :path header"); - } - if (!md.value()->get_pointer(HttpAuthorityMetadata())) { - return absl::InternalError("Missing :authority header"); - } - return std::move(*md); - }), - // Match request with requested call - [this, call](ClientMetadataHandle md) { - auto* registered_method = static_cast( - md->get(GrpcRegisteredMethod()).value_or(nullptr)); - RequestMatcherInterface* rm; - grpc_server_register_method_payload_handling payload_handling = - GRPC_SRM_PAYLOAD_NONE; - if (registered_method == nullptr) { - rm = server_->unregistered_request_matcher_.get(); - } else { - payload_handling = registered_method->payload_handling; - rm = registered_method->matcher.get(); - } - auto maybe_read_first_message = If( - payload_handling == GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER, - [call]() { return call->PullClientToServerMessage(); }, - []() -> ValueOrFailure> { - return ValueOrFailure>( - absl::nullopt); - }); - return TryJoin( - std::move(maybe_read_first_message), rm->MatchRequest(cq_idx()), - [md = std::move(md)]() mutable { - return ValueOrFailure(std::move(md)); - }); - }, - // Publish call to cq - [](std::tuple, - RequestMatcherInterface::MatchResult, - ClientMetadataHandle> - r) { - RequestMatcherInterface::MatchResult& mr = std::get<1>(r); - auto md = std::move(std::get<2>(r)); - auto* rc = mr.TakeCall(); - rc->Complete(std::move(std::get<0>(r)), *md); - auto* call_context = GetContext(); - const auto* deadline = md->get_pointer(GrpcTimeoutMetadata()); - if (deadline != nullptr) { - GetContext()->UpdateDeadline(*deadline); - } - *rc->call = call_context->c_call(); - grpc_call_ref(*rc->call); - grpc_call_set_completion_queue(call_context->c_call(), - rc->cq_bound_to_call); - call_context->server_call_context()->PublishInitialMetadata( - std::move(md), rc->initial_metadata); - // TODO(ctiller): publish metadata - return Map(WaitForCqEndOp(false, rc->tag, absl::OkStatus(), mr.cq()), - [rc = std::unique_ptr(rc)](Empty) { - return absl::OkStatus(); - }); - }); - }); -} - -ArenaPromise Server::ChannelData::MakeCallPromise( - grpc_channel_element* elem, CallArgs call_args, NextPromiseFactory) { - auto* chand = static_cast(elem->channel_data); - auto* server = chand->server_.get(); - if (server->ShutdownCalled()) return CancelledDueToServerShutdown(); - auto cleanup_ref = - absl::MakeCleanup([server] { server->ShutdownUnrefOnRequest(); }); - if (!server->ShutdownRefOnRequest()) return CancelledDueToServerShutdown(); - auto path_ptr = - call_args.client_initial_metadata->get_pointer(HttpPathMetadata()); - if (path_ptr == nullptr) { - return [] { - return ServerMetadataFromStatus( - absl::InternalError("Missing :path header")); - }; - } - auto host_ptr = - call_args.client_initial_metadata->get_pointer(HttpAuthorityMetadata()); - if (host_ptr == nullptr) { - return [] { - return ServerMetadataFromStatus( - absl::InternalError("Missing :authority header")); - }; - } - // Find request matcher. - RequestMatcherInterface* matcher; - RegisteredMethod* rm = static_cast( - call_args.client_initial_metadata->get(GrpcRegisteredMethod()) - .value_or(nullptr)); - ArenaPromise>> - maybe_read_first_message([] { return NextResult(); }); - if (rm != nullptr) { - matcher = rm->matcher.get(); - switch (rm->payload_handling) { - case GRPC_SRM_PAYLOAD_NONE: - break; - case GRPC_SRM_PAYLOAD_READ_INITIAL_BYTE_BUFFER: - maybe_read_first_message = - Map(call_args.client_to_server_messages->Next(), - [](NextResult msg) - -> absl::StatusOr> { - return std::move(msg); - }); - } - } else { - matcher = server->unregistered_request_matcher_.get(); - } - return TrySeq( - std::move(maybe_read_first_message), - [cleanup_ref = std::move(cleanup_ref), matcher, - chand](NextResult payload) mutable { - return Map( - [cleanup_ref = std::move(cleanup_ref), - mr = matcher->MatchRequest(chand->cq_idx())]() mutable { - return mr(); - }, - [payload = std::move(payload)]( - absl::StatusOr mr) mutable - -> absl::StatusOr>> { - if (!mr.ok()) return mr.status(); - return std::make_pair(std::move(*mr), std::move(payload)); - }); - }, - [call_args = - std::move(call_args)](std::pair> - r) mutable { - auto& mr = r.first; - auto& payload = r.second; - auto* rc = mr.TakeCall(); - auto* cq_for_new_request = mr.cq(); - auto* server_call_context = - GetContext()->server_call_context(); - rc->Complete(std::move(payload), *call_args.client_initial_metadata); - server_call_context->PublishInitialMetadata( - std::move(call_args.client_initial_metadata), rc->initial_metadata); - return server_call_context->MakeTopOfServerCallPromise( - std::move(call_args), rc->cq_bound_to_call, - [rc, cq_for_new_request](grpc_call* call) { - *rc->call = call; - grpc_cq_end_op(cq_for_new_request, rc->tag, absl::OkStatus(), - Server::DoneRequestEvent, rc, &rc->completion, - true); - }); - }); + calld->Start(elem); } void Server::ChannelData::FinishDestroy(void* arg, diff --git a/src/core/server/server.h b/src/core/server/server.h index 486892b14d8..01b541c233e 100644 --- a/src/core/server/server.h +++ b/src/core/server/server.h @@ -38,7 +38,9 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include #include +#include #include #include #include @@ -74,6 +76,9 @@ "grpc.server.max_pending_requests_hard_limit" namespace grpc_core { +namespace experimental { +class PassiveListenerImpl; +} // namespace experimental extern TraceFlag grpc_server_channel_trace; @@ -112,7 +117,7 @@ class Server : public ServerInterface, /// Interface for listeners. /// Implementations must override the Orphan() method, which should stop /// listening and initiate destruction of the listener. - class ListenerInterface : public Orphanable { + class ListenerInterface : public InternallyRefCounted { public: ~ListenerInterface() override = default; @@ -211,17 +216,28 @@ class Server : public ServerInterface, void SendGoaways() ABSL_LOCKS_EXCLUDED(mu_global_, mu_call_); + grpc_compression_options compression_options() const override { + return compression_options_; + } + private: + // note: the grpc_core::Server redundant namespace qualification is + // required for older gcc versions. + // TODO(yashykt): eliminate this friend statement as part of your upcoming + // server listener refactoring. + friend absl::Status(::grpc_server_add_passive_listener)( + grpc_core::Server* server, grpc_server_credentials* credentials, + std::shared_ptr + passive_listener); struct RequestedCall; class RequestMatcherInterface; - class RealRequestMatcherFilterStack; - class RealRequestMatcherPromises; + class RealRequestMatcher; class AllocatingRequestMatcherBase; class AllocatingRequestMatcherBatch; class AllocatingRequestMatcherRegistered; - class ChannelData final : public ServerTransport::Acceptor { + class ChannelData final { public: ChannelData() = default; ~ChannelData(); @@ -234,26 +250,17 @@ class Server : public ServerInterface, Channel* channel() const { return channel_.get(); } size_t cq_idx() const { return cq_idx_; } - RegisteredMethod* GetRegisteredMethod(const absl::string_view& host, - const absl::string_view& path); // Filter vtable functions. static grpc_error_handle InitChannelElement( grpc_channel_element* elem, grpc_channel_element_args* args); static void DestroyChannelElement(grpc_channel_element* elem); - static ArenaPromise MakeCallPromise( - grpc_channel_element* elem, CallArgs call_args, NextPromiseFactory); void InitCall(RefCountedPtr call); - Arena* CreateArena() override; - absl::StatusOr CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) override; - private: class ConnectivityWatcher; static void AcceptStream(void* arg, Transport* /*transport*/, const void* transport_server_data); - void SetRegisteredMethodOnMetadata(ClientMetadata& metadata); void Destroy() ABSL_EXCLUSIVE_LOCKS_REQUIRED(server_->mu_global_); @@ -384,6 +391,12 @@ class Server : public ServerInterface, using is_transparent = void; }; + class TransportConnectivityWatcher; + + RegisteredMethod* GetRegisteredMethod(const absl::string_view& host, + const absl::string_view& path); + void SetRegisteredMethodOnMetadata(ClientMetadata& metadata); + static void ListenerDestroyDone(void* arg, grpc_error_handle error); static void DoneShutdownEvent(void* server, @@ -445,6 +458,10 @@ class Server : public ServerInterface, return shutdown_refs_.load(std::memory_order_acquire) == 0; } + auto MatchAndPublishCall(CallHandler call_handler); + absl::StatusOr> MakeCallDestination( + const ChannelArgs& args); + ChannelArgs const channel_args_; RefCountedPtr channelz_node_; std::unique_ptr config_fetcher_; @@ -453,6 +470,7 @@ class Server : public ServerInterface, std::vector cqs_; std::vector pollsets_; bool started_ = false; + const grpc_compression_options compression_options_; // The two following mutexes control access to server-state. // mu_global_ controls access to non-call-related state (e.g., channel state). @@ -500,6 +518,9 @@ class Server : public ServerInterface, absl::BitGen bitgen_ ABSL_GUARDED_BY(mu_call_); std::list channels_; + absl::flat_hash_set> connections_ + ABSL_GUARDED_BY(mu_global_); + size_t connections_open_ ABSL_GUARDED_BY(mu_global_) = 0; std::list listeners_; size_t listeners_destroyed_ = 0; diff --git a/src/core/server/server_interface.h b/src/core/server/server_interface.h index 3cb7b1702ff..431ad369714 100644 --- a/src/core/server/server_interface.h +++ b/src/core/server/server_interface.h @@ -17,6 +17,7 @@ #ifndef GRPC_SRC_CORE_SERVER_SERVER_INTERFACE_H #define GRPC_SRC_CORE_SERVER_SERVER_INTERFACE_H +#include #include #include "src/core/channelz/channelz.h" @@ -36,6 +37,7 @@ class ServerInterface { virtual const ChannelArgs& channel_args() const = 0; virtual channelz::ServerNode* channelz_node() const = 0; virtual ServerCallTracerFactory* server_call_tracer_factory() const = 0; + virtual grpc_compression_options compression_options() const = 0; }; } // namespace grpc_core diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc index 11849b655b8..fa22ca884b7 100644 --- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc @@ -23,6 +23,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "upb/mem/arena.hpp" #include @@ -87,7 +88,7 @@ typedef struct alts_tsi_handshaker_result { static tsi_result handshaker_result_extract_peer( const tsi_handshaker_result* self, tsi_peer* peer) { if (self == nullptr || peer == nullptr) { - gpr_log(GPR_ERROR, "Invalid argument to handshaker_result_extract_peer()"); + LOG(ERROR) << "Invalid argument to handshaker_result_extract_peer()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -97,7 +98,7 @@ static tsi_result handshaker_result_extract_peer( tsi_result ok = tsi_construct_peer(kTsiAltsNumOfPeerProperties, peer); int index = 0; if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to construct tsi peer"); + LOG(ERROR) << "Failed to construct tsi peer"; return ok; } CHECK_NE(&peer->properties[index], nullptr); @@ -106,7 +107,7 @@ static tsi_result handshaker_result_extract_peer( &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; return ok; } index++; @@ -116,7 +117,7 @@ static tsi_result handshaker_result_extract_peer( &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } index++; CHECK_NE(&peer->properties[index], nullptr); @@ -126,7 +127,7 @@ static tsi_result handshaker_result_extract_peer( GRPC_SLICE_LENGTH(result->rpc_versions), &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } index++; CHECK_NE(&peer->properties[index], nullptr); @@ -136,7 +137,7 @@ static tsi_result handshaker_result_extract_peer( GRPC_SLICE_LENGTH(result->serialized_context), &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } index++; CHECK_NE(&peer->properties[index], nullptr); @@ -146,7 +147,7 @@ static tsi_result handshaker_result_extract_peer( &peer->properties[index]); if (ok != TSI_OK) { tsi_peer_destruct(peer); - gpr_log(GPR_ERROR, "Failed to set tsi peer property"); + LOG(ERROR) << "Failed to set tsi peer property"; } CHECK(++index == kTsiAltsNumOfPeerProperties); return ok; @@ -163,8 +164,7 @@ static tsi_result handshaker_result_create_zero_copy_grpc_protector( const tsi_handshaker_result* self, size_t* max_output_protected_frame_size, tsi_zero_copy_grpc_protector** protector) { if (self == nullptr || protector == nullptr) { - gpr_log(GPR_ERROR, - "Invalid arguments to create_zero_copy_grpc_protector()"); + LOG(ERROR) << "Invalid arguments to create_zero_copy_grpc_protector()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -198,7 +198,7 @@ static tsi_result handshaker_result_create_zero_copy_grpc_protector( /*is_integrity_only=*/false, /*enable_extra_copy=*/false, max_output_protected_frame_size, protector); if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to create zero-copy grpc protector"); + LOG(ERROR) << "Failed to create zero-copy grpc protector"; } return ok; } @@ -207,8 +207,8 @@ static tsi_result handshaker_result_create_frame_protector( const tsi_handshaker_result* self, size_t* max_output_protected_frame_size, tsi_frame_protector** protector) { if (self == nullptr || protector == nullptr) { - gpr_log(GPR_ERROR, - "Invalid arguments to handshaker_result_create_frame_protector()"); + LOG(ERROR) + << "Invalid arguments to handshaker_result_create_frame_protector()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -219,7 +219,7 @@ static tsi_result handshaker_result_create_frame_protector( kAltsAes128GcmRekeyKeyLength, result->is_client, /*is_rekey=*/true, max_output_protected_frame_size, protector); if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to create frame protector"); + LOG(ERROR) << "Failed to create frame protector"; } return ok; } @@ -228,8 +228,7 @@ static tsi_result handshaker_result_get_unused_bytes( const tsi_handshaker_result* self, const unsigned char** bytes, size_t* bytes_size) { if (self == nullptr || bytes == nullptr || bytes_size == nullptr) { - gpr_log(GPR_ERROR, - "Invalid arguments to handshaker_result_get_unused_bytes()"); + LOG(ERROR) << "Invalid arguments to handshaker_result_get_unused_bytes()"; return TSI_INVALID_ARGUMENT; } alts_tsi_handshaker_result* result = @@ -267,7 +266,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, bool is_client, tsi_handshaker_result** result) { if (result == nullptr || resp == nullptr) { - gpr_log(GPR_ERROR, "Invalid arguments to create_handshaker_result()"); + LOG(ERROR) << "Invalid arguments to create_handshaker_result()"; return TSI_INVALID_ARGUMENT; } const grpc_gcp_HandshakerResult* hresult = @@ -275,42 +274,42 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, const grpc_gcp_Identity* identity = grpc_gcp_HandshakerResult_peer_identity(hresult); if (identity == nullptr) { - gpr_log(GPR_ERROR, "Invalid identity"); + LOG(ERROR) << "Invalid identity"; return TSI_FAILED_PRECONDITION; } upb_StringView peer_service_account = grpc_gcp_Identity_service_account(identity); if (peer_service_account.size == 0) { - gpr_log(GPR_ERROR, "Invalid peer service account"); + LOG(ERROR) << "Invalid peer service account"; return TSI_FAILED_PRECONDITION; } upb_StringView key_data = grpc_gcp_HandshakerResult_key_data(hresult); if (key_data.size < kAltsAes128GcmRekeyKeyLength) { - gpr_log(GPR_ERROR, "Bad key length"); + LOG(ERROR) << "Bad key length"; return TSI_FAILED_PRECONDITION; } const grpc_gcp_RpcProtocolVersions* peer_rpc_version = grpc_gcp_HandshakerResult_peer_rpc_versions(hresult); if (peer_rpc_version == nullptr) { - gpr_log(GPR_ERROR, "Peer does not set RPC protocol versions."); + LOG(ERROR) << "Peer does not set RPC protocol versions."; return TSI_FAILED_PRECONDITION; } upb_StringView application_protocol = grpc_gcp_HandshakerResult_application_protocol(hresult); if (application_protocol.size == 0) { - gpr_log(GPR_ERROR, "Invalid application protocol"); + LOG(ERROR) << "Invalid application protocol"; return TSI_FAILED_PRECONDITION; } upb_StringView record_protocol = grpc_gcp_HandshakerResult_record_protocol(hresult); if (record_protocol.size == 0) { - gpr_log(GPR_ERROR, "Invalid record protocol"); + LOG(ERROR) << "Invalid record protocol"; return TSI_FAILED_PRECONDITION; } const grpc_gcp_Identity* local_identity = grpc_gcp_HandshakerResult_local_identity(hresult); if (local_identity == nullptr) { - gpr_log(GPR_ERROR, "Invalid local identity"); + LOG(ERROR) << "Invalid local identity"; return TSI_FAILED_PRECONDITION; } upb_StringView local_service_account = @@ -331,7 +330,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, bool serialized = grpc_gcp_rpc_protocol_versions_encode( peer_rpc_version, rpc_versions_arena.ptr(), &sresult->rpc_versions); if (!serialized) { - gpr_log(GPR_ERROR, "Failed to serialize peer's RPC protocol versions."); + LOG(ERROR) << "Failed to serialize peer's RPC protocol versions."; return TSI_FAILED_PRECONDITION; } upb::Arena context_arena; @@ -348,7 +347,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, context, const_cast(peer_rpc_version)); grpc_gcp_Identity* peer_identity = const_cast(identity); if (peer_identity == nullptr) { - gpr_log(GPR_ERROR, "Null peer identity in ALTS context."); + LOG(ERROR) << "Null peer identity in ALTS context."; return TSI_FAILED_PRECONDITION; } if (grpc_gcp_Identity_attributes_size(identity) != 0) { @@ -372,7 +371,7 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_HandshakerResp* resp, char* serialized_ctx = grpc_gcp_AltsContext_serialize( context, context_arena.ptr(), &serialized_ctx_length); if (serialized_ctx == nullptr) { - gpr_log(GPR_ERROR, "Failed to serialize peer's ALTS context."); + LOG(ERROR) << "Failed to serialize peer's ALTS context."; return TSI_FAILED_PRECONDITION; } sresult->serialized_context = @@ -388,7 +387,7 @@ static void on_handshaker_service_resp_recv(void* arg, grpc_error_handle error) { alts_handshaker_client* client = static_cast(arg); if (client == nullptr) { - gpr_log(GPR_ERROR, "ALTS handshaker client is nullptr"); + LOG(ERROR) << "ALTS handshaker client is nullptr"; return; } bool success = true; @@ -440,7 +439,7 @@ static tsi_result alts_tsi_handshaker_continue_handshaker_next( handshaker->client_vtable_for_testing, handshaker->is_client, handshaker->max_frame_size, error); if (client == nullptr) { - gpr_log(GPR_ERROR, "Failed to create ALTS handshaker client"); + LOG(ERROR) << "Failed to create ALTS handshaker client"; if (error != nullptr) *error = "Failed to create ALTS handshaker client"; return TSI_FAILED_PRECONDITION; } @@ -449,7 +448,7 @@ static tsi_result alts_tsi_handshaker_continue_handshaker_next( CHECK_EQ(handshaker->client, nullptr); handshaker->client = client; if (handshaker->shutdown) { - gpr_log(GPR_INFO, "TSI handshake shutdown"); + LOG(INFO) << "TSI handshake shutdown"; if (error != nullptr) *error = "TSI handshaker shutdown"; return TSI_HANDSHAKE_SHUTDOWN; } @@ -529,7 +528,7 @@ static tsi_result handshaker_next( size_t* /*bytes_to_send_size*/, tsi_handshaker_result** /*result*/, tsi_handshaker_on_next_done_cb cb, void* user_data, std::string* error) { if (self == nullptr || cb == nullptr) { - gpr_log(GPR_ERROR, "Invalid arguments to handshaker_next()"); + LOG(ERROR) << "Invalid arguments to handshaker_next()"; if (error != nullptr) *error = "invalid argument"; return TSI_INVALID_ARGUMENT; } @@ -538,7 +537,7 @@ static tsi_result handshaker_next( { grpc_core::MutexLock lock(&handshaker->mu); if (handshaker->shutdown) { - gpr_log(GPR_INFO, "TSI handshake shutdown"); + LOG(INFO) << "TSI handshake shutdown"; if (error != nullptr) *error = "handshake shutdown"; return TSI_HANDSHAKE_SHUTDOWN; } @@ -569,7 +568,7 @@ static tsi_result handshaker_next( tsi_result ok = alts_tsi_handshaker_continue_handshaker_next( handshaker, received_bytes, received_bytes_size, cb, user_data, error); if (ok != TSI_OK) { - gpr_log(GPR_ERROR, "Failed to schedule ALTS handshaker requests"); + LOG(ERROR) << "Failed to schedule ALTS handshaker requests"; return ok; } } @@ -651,7 +650,7 @@ tsi_result alts_tsi_handshaker_create( size_t user_specified_max_frame_size) { if (handshaker_service_url == nullptr || self == nullptr || options == nullptr || (is_client && target_name == nullptr)) { - gpr_log(GPR_ERROR, "Invalid arguments to alts_tsi_handshaker_create()"); + LOG(ERROR) << "Invalid arguments to alts_tsi_handshaker_create()"; return TSI_INVALID_ARGUMENT; } bool use_dedicated_cq = interested_parties == nullptr; diff --git a/src/core/xds/grpc/xds_client_grpc.cc b/src/core/xds/grpc/xds_client_grpc.cc index 4408f96e2b6..7b7fee2ca76 100644 --- a/src/core/xds/grpc/xds_client_grpc.cc +++ b/src/core/xds/grpc/xds_client_grpc.cc @@ -99,20 +99,20 @@ const auto kMetricResourceUpdatesValid = "EXPERIMENTAL. A counter of resources received that were considered " "valid. The counter will be incremented even for resources that " "have not changed.", - "{resource}", - {kMetricLabelTarget, kMetricLabelXdsServer, - kMetricLabelXdsResourceType}, - {}, false); + "{resource}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer, + kMetricLabelXdsResourceType) + .Build(); const auto kMetricResourceUpdatesInvalid = GlobalInstrumentsRegistry::RegisterUInt64Counter( "grpc.xds_client.resource_updates_invalid", "EXPERIMENTAL. A counter of resources received that were considered " "invalid.", - "{resource}", - {kMetricLabelTarget, kMetricLabelXdsServer, - kMetricLabelXdsResourceType}, - {}, false); + "{resource}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer, + kMetricLabelXdsResourceType) + .Build(); const auto kMetricServerFailure = GlobalInstrumentsRegistry::RegisterUInt64Counter( @@ -121,7 +121,9 @@ const auto kMetricServerFailure = "unhealthy. A server goes unhealthy when we have a connectivity " "failure or when the ADS stream fails without seeing a response " "message, as per gRFC A57.", - "{failure}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false); + "{failure}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer) + .Build(); const auto kMetricConnected = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( @@ -132,15 +134,17 @@ const auto kMetricConnected = "ADS stream fails without seeing a response message, as per gRFC " "A57. It will be set to 1 when we receive the first response on " "an ADS stream.", - "{bool}", {kMetricLabelTarget, kMetricLabelXdsServer}, {}, false); + "{bool}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsServer) + .Build(); const auto kMetricResources = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( "grpc.xds_client.resources", "EXPERIMENTAL. Number of xDS resources.", - "{resource}", - {kMetricLabelTarget, kMetricLabelXdsAuthority, - kMetricLabelXdsResourceType, kMetricLabelXdsCacheState}, - {}, false); + "{resource}", false) + .Labels(kMetricLabelTarget, kMetricLabelXdsAuthority, + kMetricLabelXdsResourceType, kMetricLabelXdsCacheState) + .Build(); } // namespace @@ -316,7 +320,7 @@ GrpcXdsClient::GrpcXdsClient( [this](CallbackMetricReporter& reporter) { ReportCallbackMetrics(reporter); }, - {kMetricConnected, kMetricResources})) {} + Duration::Seconds(5), kMetricConnected, kMetricResources)) {} void GrpcXdsClient::Orphaned() { registered_metric_callback_.reset(); diff --git a/src/cpp/ext/csm/BUILD b/src/cpp/ext/csm/BUILD index fda0e37dbe8..6ee6bef1d4a 100644 --- a/src/cpp/ext/csm/BUILD +++ b/src/cpp/ext/csm/BUILD @@ -42,6 +42,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/types:optional", diff --git a/src/cpp/ext/gcp/BUILD b/src/cpp/ext/gcp/BUILD index a95fe68b71c..814bf9012a2 100644 --- a/src/cpp/ext/gcp/BUILD +++ b/src/cpp/ext/gcp/BUILD @@ -115,6 +115,7 @@ grpc_cc_library( ], external_deps = [ "absl/base:core_headers", + "absl/log:log", "absl/numeric:int128", "absl/strings", "absl/strings:str_format", @@ -157,6 +158,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/types:optional", diff --git a/src/cpp/ext/otel/otel_plugin.cc b/src/cpp/ext/otel/otel_plugin.cc index 18e0069a72a..acb81be35ee 100644 --- a/src/cpp/ext/otel/otel_plugin.cc +++ b/src/cpp/ext/otel/otel_plugin.cc @@ -249,27 +249,35 @@ OpenTelemetryPlugin::CallbackMetricReporter::CallbackMetricReporter( // that if a particular combination of labels was previously present but // is no longer present, we won't continue to report it. for (const auto& handle : key->metrics()) { - grpc_core::Match( - handle, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackInt64GaugeHandle& handle) { - auto& callback_gauge_state = - absl::get>>( - ot_plugin_->instruments_data_.at(handle.index).instrument); - callback_gauge_state->caches[key].clear(); - }, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackDoubleGaugeHandle& handle) { - auto& callback_gauge_state = - absl::get>>( - ot_plugin_->instruments_data_.at(handle.index).instrument); - callback_gauge_state->caches[key].clear(); - }); + const auto& descriptor = + grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle); + GPR_ASSERT( + descriptor.instrument_type == + grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); + switch (descriptor.value_type) { + case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: { + auto& callback_gauge_state = + absl::get>>( + ot_plugin_->instruments_data_.at(handle.index).instrument); + callback_gauge_state->caches[key].clear(); + break; + } + case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: { + auto& callback_gauge_state = + absl::get>>( + ot_plugin_->instruments_data_.at(handle.index).instrument); + callback_gauge_state->caches[key].clear(); + break; + } + default: + grpc_core::Crash(absl::StrFormat( + "Unknown or unsupported value type: %d", descriptor.value_type)); + } } } -void OpenTelemetryPlugin::CallbackMetricReporter::Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, +void OpenTelemetryPlugin::CallbackMetricReporter::ReportInt64( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index); @@ -296,9 +304,8 @@ void OpenTelemetryPlugin::CallbackMetricReporter::Report( cell.insert_or_assign(std::move(key), value); } -void OpenTelemetryPlugin::CallbackMetricReporter::Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle - handle, +void OpenTelemetryPlugin::CallbackMetricReporter::ReportDouble( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = ot_plugin_->instruments_data_.at(handle.index); @@ -574,8 +581,8 @@ OpenTelemetryPlugin::IsEnabledForChannel( std::pair> OpenTelemetryPlugin::IsEnabledForServer( const grpc_core::ChannelArgs& args) const { - // Return true only if there is no server selector registered or if the server - // selector returns true. + // Return true only if there is no server selector registered or if the + // server selector returns true. if (server_selector_ == nullptr || server_selector_(args)) { return {true, std::make_shared(this, args)}; } @@ -583,7 +590,7 @@ OpenTelemetryPlugin::IsEnabledForServer( } void OpenTelemetryPlugin::AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -607,7 +614,7 @@ void OpenTelemetryPlugin::AddCounter( } void OpenTelemetryPlugin::AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -631,7 +638,7 @@ void OpenTelemetryPlugin::AddCounter( } void OpenTelemetryPlugin::RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -657,7 +664,7 @@ void OpenTelemetryPlugin::RecordHistogram( } void OpenTelemetryPlugin::RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) { const auto& instrument_data = instruments_data_.at(handle.index); @@ -691,51 +698,59 @@ void OpenTelemetryPlugin::AddCallback( grpc_core::MutexLock lock(&mu_); callback_timestamps_.emplace(callback, grpc_core::Timestamp::InfPast()); for (const auto& handle : callback->metrics()) { - grpc_core::Match( - handle, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackInt64GaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - (*callback_gauge_state) - ->caches.emplace(callback, - CallbackGaugeState::Cache{}); - if (!std::exchange((*callback_gauge_state)->ot_callback_registered, - true)) { - gauges_that_need_to_add_callback.push_back( - callback_gauge_state->get()); - } - }, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackDoubleGaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - (*callback_gauge_state) - ->caches.emplace(callback, CallbackGaugeState::Cache{}); - if (!std::exchange((*callback_gauge_state)->ot_callback_registered, - true)) { - gauges_that_need_to_add_callback.push_back( - callback_gauge_state->get()); - } - }); + const auto& descriptor = + grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle); + GPR_ASSERT( + descriptor.instrument_type == + grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); + switch (descriptor.value_type) { + case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + (*callback_gauge_state) + ->caches.emplace(callback, CallbackGaugeState::Cache{}); + if (!std::exchange((*callback_gauge_state)->ot_callback_registered, + true)) { + gauges_that_need_to_add_callback.push_back( + callback_gauge_state->get()); + } + break; + } + case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + (*callback_gauge_state) + ->caches.emplace(callback, CallbackGaugeState::Cache{}); + if (!std::exchange((*callback_gauge_state)->ot_callback_registered, + true)) { + gauges_that_need_to_add_callback.push_back( + callback_gauge_state->get()); + } + break; + } + default: + grpc_core::Crash(absl::StrFormat( + "Unknown or unsupported value type: %d", descriptor.value_type)); + } } } - // AddCallback internally grabs OpenTelemetry's observable_registry's lock. So - // we need to call it without our plugin lock otherwise we may deadlock. + // AddCallback internally grabs OpenTelemetry's observable_registry's + // lock. So we need to call it without our plugin lock otherwise we may + // deadlock. for (const auto& gauge : gauges_that_need_to_add_callback) { grpc_core::Match( gauge, @@ -759,50 +774,59 @@ void OpenTelemetryPlugin::RemoveCallback( grpc_core::MutexLock lock(&mu_); callback_timestamps_.erase(callback); for (const auto& handle : callback->metrics()) { - grpc_core::Match( - handle, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackInt64GaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - CHECK((*callback_gauge_state)->ot_callback_registered); - CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); - if ((*callback_gauge_state)->caches.empty()) { - gauges_that_need_to_remove_callback.push_back( - callback_gauge_state->get()); - (*callback_gauge_state)->ot_callback_registered = false; - } - }, - [&](const grpc_core::GlobalInstrumentsRegistry:: - GlobalCallbackDoubleGaugeHandle& handle) { - const auto& instrument_data = instruments_data_.at(handle.index); - if (absl::holds_alternative(instrument_data.instrument)) { - // This instrument is disabled. - return; - } - auto* callback_gauge_state = - absl::get_if>>( - &instrument_data.instrument); - CHECK_NE(callback_gauge_state, nullptr); - CHECK((*callback_gauge_state)->ot_callback_registered); - CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); - if ((*callback_gauge_state)->caches.empty()) { - gauges_that_need_to_remove_callback.push_back( - callback_gauge_state->get()); - (*callback_gauge_state)->ot_callback_registered = false; - } - }); + const auto& descriptor = + grpc_core::GlobalInstrumentsRegistry::GetInstrumentDescriptor(handle); + GPR_ASSERT( + descriptor.instrument_type == + grpc_core::GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); + switch (descriptor.value_type) { + case grpc_core::GlobalInstrumentsRegistry::ValueType::kInt64: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + CHECK((*callback_gauge_state)->ot_callback_registered); + CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); + if ((*callback_gauge_state)->caches.empty()) { + gauges_that_need_to_remove_callback.push_back( + callback_gauge_state->get()); + (*callback_gauge_state)->ot_callback_registered = false; + } + break; + } + case grpc_core::GlobalInstrumentsRegistry::ValueType::kDouble: { + const auto& instrument_data = instruments_data_.at(handle.index); + if (absl::holds_alternative(instrument_data.instrument)) { + // This instrument is disabled. + continue; + } + auto* callback_gauge_state = + absl::get_if>>( + &instrument_data.instrument); + CHECK_NE(callback_gauge_state, nullptr); + CHECK((*callback_gauge_state)->ot_callback_registered); + CHECK_EQ((*callback_gauge_state)->caches.erase(callback), 1u); + if ((*callback_gauge_state)->caches.empty()) { + gauges_that_need_to_remove_callback.push_back( + callback_gauge_state->get()); + (*callback_gauge_state)->ot_callback_registered = false; + } + break; + } + default: + grpc_core::Crash(absl::StrFormat( + "Unknown or unsupported value type: %d", descriptor.value_type)); + } } } - // RemoveCallback internally grabs OpenTelemetry's observable_registry's lock. - // So we need to call it without our plugin lock otherwise we may deadlock. + // RemoveCallback internally grabs OpenTelemetry's observable_registry's + // lock. So we need to call it without our plugin lock otherwise we may + // deadlock. for (const auto& gauge : gauges_that_need_to_remove_callback) { grpc_core::Match( gauge, @@ -842,7 +866,8 @@ void OpenTelemetryPlugin::CallbackGaugeState::Observe( } } -// OpenTelemetry calls our callback with its observable_registry's lock held. +// OpenTelemetry calls our callback with its observable_registry's lock +// held. template void OpenTelemetryPlugin::CallbackGaugeState::CallbackGaugeCallback( opentelemetry::metrics::ObserverResult result, void* arg) { diff --git a/src/cpp/ext/otel/otel_plugin.h b/src/cpp/ext/otel/otel_plugin.h index 6908f2b7ab4..49d2cc3e384 100644 --- a/src/cpp/ext/otel/otel_plugin.h +++ b/src/cpp/ext/otel/otel_plugin.h @@ -343,22 +343,20 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin { grpc_core::RegisteredMetricCallback* key) ABSL_EXCLUSIVE_LOCKS_REQUIRED(ot_plugin->mu_); - void Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle - handle, + private: + void ReportInt64( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, absl::Span label_values, absl::Span optional_values) ABSL_EXCLUSIVE_LOCKS_REQUIRED( CallbackGaugeState::ot_plugin->mu_) override; - void Report( - grpc_core::GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle - handle, + void ReportDouble( + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) ABSL_EXCLUSIVE_LOCKS_REQUIRED( CallbackGaugeState::ot_plugin->mu_) override; - private: OpenTelemetryPlugin* ot_plugin_; grpc_core::RegisteredMetricCallback* key_; }; @@ -380,19 +378,19 @@ class OpenTelemetryPlugin : public grpc_core::StatsPlugin { std::pair> IsEnabledForServer(const grpc_core::ChannelArgs& args) const override; void AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) override; void AddCounter( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) override; void RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, absl::Span label_values, absl::Span optional_values) override; void RecordHistogram( - grpc_core::GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, + grpc_core::GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) override; void AddCallback(grpc_core::RegisteredMetricCallback* callback) diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index f989703fe1a..b9f71915981 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -47,11 +48,38 @@ #include #include +#include "src/core/ext/transport/chttp2/server/chttp2_server.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" +#include "src/core/server/server.h" #include "src/cpp/server/external_connection_acceptor_impl.h" namespace grpc { +namespace { + +// A PIMPL wrapper class that owns the only ref to the passive listener +// implementation. This is returned to the application. +class PassiveListenerOwner final + : public grpc_core::experimental::PassiveListener { + public: + explicit PassiveListenerOwner(std::shared_ptr listener) + : listener_(std::move(listener)) {} + + absl::Status AcceptConnectedEndpoint( + std::unique_ptr + endpoint) override { + return listener_->AcceptConnectedEndpoint(std::move(endpoint)); + } + + absl::Status AcceptConnectedFd(int fd) override { + return listener_->AcceptConnectedFd(fd); + } + + private: + std::shared_ptr listener_; +}; + +} // namespace static std::vector (*)()>* g_plugin_factory_list; @@ -225,6 +253,18 @@ ServerBuilder& ServerBuilder::SetResourceQuota( return *this; } +ServerBuilder& ServerBuilder::experimental_type::AddPassiveListener( + std::shared_ptr creds, + std::unique_ptr& passive_listener) { + auto core_passive_listener = + std::make_shared(); + builder_->unstarted_passive_listeners_.emplace_back(core_passive_listener, + std::move(creds)); + passive_listener = + std::make_unique(std::move(core_passive_listener)); + return *builder_; +} + ServerBuilder& ServerBuilder::AddListeningPort( const std::string& addr_uri, std::shared_ptr creds, int* selected_port) { @@ -398,6 +438,26 @@ std::unique_ptr ServerBuilder::BuildAndStart() { cq->RegisterServer(server.get()); } + for (auto& unstarted_listener : unstarted_passive_listeners_) { + has_frequently_polled_cqs = true; + auto passive_listener = unstarted_listener.passive_listener.lock(); + auto* core_server = grpc_core::Server::FromC(server->c_server()); + if (passive_listener != nullptr) { + auto* creds = unstarted_listener.credentials->c_creds(); + if (creds == nullptr) { + gpr_log(GPR_ERROR, "Credentials missing for PassiveListener"); + return nullptr; + } + auto success = grpc_server_add_passive_listener( + core_server, creds, std::move(passive_listener)); + if (!success.ok()) { + gpr_log(GPR_ERROR, "Failed to create a passive listener: %s", + success.ToString().c_str()); + return nullptr; + } + } + } + if (!has_frequently_polled_cqs) { gpr_log(GPR_ERROR, "At least one of the completion queues must be frequently polled"); diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 377dac99484..f00614f2c35 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -736,6 +736,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/transport/call_spine.cc', 'src/core/lib/transport/connectivity_state.cc', 'src/core/lib/transport/error_utils.cc', + 'src/core/lib/transport/interception_chain.cc', 'src/core/lib/transport/message.cc', 'src/core/lib/transport/metadata.cc', 'src/core/lib/transport/metadata_batch.cc', diff --git a/templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template new file mode 100644 index 00000000000..f3a5a484e2e --- /dev/null +++ b/templates/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile.template @@ -0,0 +1,28 @@ +%YAML 1.2 +--- | + # Copyright 2021 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. + + FROM gcc:7 + + RUN apt-get update && apt-get install -y curl git time wget zip && apt-get clean + <%include file="../../git_avoid_dubious_ownership_error.include"/> + <%include file="../../run_tests_python_deps.include"/> + <%include file="../../cxx_test_deps.include"/> + <%include file="../../cmake.include"/> + <%include file="../../ccache_old.include"/> + <%include file="../../run_tests_addons.include"/> + + # Define the default command. + CMD ["bash"] diff --git a/test/core/address_utils/BUILD b/test/core/address_utils/BUILD index 15f41c3f9d5..ceb5a12dbb6 100644 --- a/test/core/address_utils/BUILD +++ b/test/core/address_utils/BUILD @@ -41,6 +41,7 @@ grpc_cc_test( name = "parse_address_test", srcs = ["parse_address_test.cc"], external_deps = [ + "absl/log:log", "absl/strings", "gtest", ], @@ -69,7 +70,10 @@ grpc_fuzzer( grpc_cc_test( name = "parse_address_with_named_scope_id_test", srcs = ["parse_address_with_named_scope_id_test.cc"], - external_deps = ["gtest"], + external_deps = [ + "absl/log:log", + "gtest", + ], language = "C++", tags = ["no_windows"], uses_event_engine = False, diff --git a/test/core/address_utils/parse_address_test.cc b/test/core/address_utils/parse_address_test.cc index d94370556e5..41b9df4bd5d 100644 --- a/test/core/address_utils/parse_address_test.cc +++ b/test/core/address_utils/parse_address_test.cc @@ -34,12 +34,12 @@ #include +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/strings/match.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/port.h" @@ -53,7 +53,7 @@ static void test_grpc_parse_unix(const char* uri_text, const char* pathname) { grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -70,7 +70,7 @@ static void test_grpc_parse_unix_abstract(const char* uri_text, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -98,7 +98,7 @@ static void test_grpc_parse_vsock(const char* uri_text, uint32_t cid, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -122,7 +122,7 @@ static void test_grpc_parse_ipv4(const char* uri_text, const char* host, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -142,7 +142,7 @@ static void test_grpc_parse_ipv6(const char* uri_text, const char* host, grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; @@ -162,7 +162,7 @@ static void test_grpc_parse_ipv6_invalid(const char* uri_text) { grpc_core::ExecCtx exec_ctx; absl::StatusOr uri = grpc_core::URI::Parse(uri_text); if (!uri.ok()) { - gpr_log(GPR_ERROR, "%s", uri.status().ToString().c_str()); + LOG(ERROR) << uri.status(); ASSERT_TRUE(uri.ok()); } grpc_resolved_address addr; diff --git a/test/core/address_utils/parse_address_with_named_scope_id_test.cc b/test/core/address_utils/parse_address_with_named_scope_id_test.cc index a69fa0072b8..eb76adef43d 100644 --- a/test/core/address_utils/parse_address_with_named_scope_id_test.cc +++ b/test/core/address_utils/parse_address_with_named_scope_id_test.cc @@ -28,13 +28,13 @@ #include +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_format.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/address_utils/parse_address.h" #include "src/core/lib/gprpp/crash.h" @@ -114,10 +114,8 @@ TEST(ParseAddressWithNamedScopeIdTest, MainTest) { // system recognizes, and then use that for the test. for (size_t i = 1; i < 65536; i++) { if (if_indextoname(i, arbitrary_interface_name) != nullptr) { - gpr_log(GPR_DEBUG, - "Found interface at index %" PRIuPTR - " named %s. Will use this for the test", - i, arbitrary_interface_name); + VLOG(2) << "Found interface at index " << i << " named " + << arbitrary_interface_name << ". Will use this for the test"; break; } } @@ -127,9 +125,8 @@ TEST(ParseAddressWithNamedScopeIdTest, MainTest) { struct sockaddr_in6 result_from_getaddrinfo = resolve_with_gettaddrinfo(target.c_str()); // Run the test - gpr_log(GPR_DEBUG, - "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: %s", - target.c_str()); + VLOG(2) << "Run test_grpc_parse_ipv6_parity_with_getaddrinfo with target: " + << target; test_grpc_parse_ipv6_parity_with_getaddrinfo(target.c_str(), result_from_getaddrinfo); // Cleanup diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc index ee7e1ee4d39..f11000ead0f 100644 --- a/test/core/bad_client/bad_client.cc +++ b/test/core/bad_client/bad_client.cc @@ -22,11 +22,11 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include #include -#include #include #include @@ -111,11 +111,11 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, hex = gpr_dump(arg->client_payload, arg->client_payload_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); // Add a debug log - gpr_log(GPR_INFO, "TEST: %s", hex); + LOG(INFO) << "TEST: " << hex; gpr_free(hex); } else { - gpr_log(GPR_INFO, "TEST: (%" PRIdPTR " byte long string)", - arg->client_payload_length); + LOG(INFO) << "TEST: (" << arg->client_payload_length + << " byte long string)"; } grpc_slice slice = grpc_slice_from_copied_buffer(arg->client_payload, @@ -171,9 +171,8 @@ void grpc_run_client_side_validator(grpc_bad_client_arg* arg, uint32_t flags, .type == GRPC_QUEUE_TIMEOUT); } while (!gpr_event_get(&read_done_event)); if (arg->client_validator(&incoming, arg->client_validator_arg)) break; - gpr_log(GPR_INFO, - "client validator failed; trying additional read " - "in case we didn't get all the data"); + LOG(INFO) << "client validator failed; trying additional read " + "in case we didn't get all the data"; } grpc_slice_buffer_destroy(&incoming); } @@ -317,7 +316,7 @@ bool rst_stream_client_validator(grpc_slice_buffer* incoming, void* /*arg*/) { *p++ == 0 || *p++ == 0 || *p++ == 0 || *p == 0 || *p == 11; if (!success) { - gpr_log(GPR_INFO, "client expected RST_STREAM frame, not found"); + LOG(INFO) << "client expected RST_STREAM frame, not found"; } grpc_slice_buffer_destroy(&last_frame_buffer); diff --git a/test/core/bad_client/generate_tests.bzl b/test/core/bad_client/generate_tests.bzl index 620fb5a114e..2ae6c1b3c42 100755 --- a/test/core/bad_client/generate_tests.bzl +++ b/test/core/bad_client/generate_tests.bzl @@ -44,6 +44,10 @@ def grpc_bad_client_tests(): hdrs = ["bad_client.h"], language = "C++", testonly = 1, + external_deps = [ + "absl/log:check", + "absl/log:log", + ], deps = [ "//test/core/test_util:grpc_test_util", "//:grpc", @@ -51,9 +55,6 @@ def grpc_bad_client_tests(): "//test/core/end2end:cq_verifier", "//:grpc_http_filters", ], - external_deps = [ - "absl/log:check", - ], ) for t, topt in BAD_CLIENT_TESTS.items(): grpc_cc_test( diff --git a/test/core/bad_connection/BUILD b/test/core/bad_connection/BUILD index d424ba888ac..5c674673037 100644 --- a/test/core/bad_connection/BUILD +++ b/test/core/bad_connection/BUILD @@ -23,7 +23,10 @@ grpc_cc_binary( srcs = [ "close_fd_test.cc", ], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", tags = ["no_windows"], deps = [ diff --git a/test/core/bad_connection/close_fd_test.cc b/test/core/bad_connection/close_fd_test.cc index a51f141270e..d3d69c8c068 100644 --- a/test/core/bad_connection/close_fd_test.cc +++ b/test/core/bad_connection/close_fd_test.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/statusor.h" #include "absl/strings/str_format.h" @@ -53,7 +54,6 @@ #include #include #include -#include #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/gprpp/crash.h" @@ -225,8 +225,8 @@ static void _test_close_before_server_recv(fd_type fdtype) { grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer* response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_recv", - fd_type_str(fdtype)); + LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype) + << "_before_server_recv"; test_init(); grpc_op ops[6]; @@ -399,8 +399,8 @@ static void _test_close_before_server_send(fd_type fdtype) { grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer* response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - gpr_log(GPR_INFO, "Running test: test_close_%s_before_server_send", - fd_type_str(fdtype)); + LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype) + << "_before_server_send"; test_init(); grpc_op ops[6]; @@ -596,8 +596,8 @@ static void _test_close_before_client_send(fd_type fdtype) { grpc_raw_byte_buffer_create(&request_payload_slice, 1); grpc_byte_buffer* response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); - gpr_log(GPR_INFO, "Running test: test_close_%s_before_client_send", - fd_type_str(fdtype)); + LOG(INFO) << "Running test: test_close_" << fd_type_str(fdtype) + << "_before_client_send"; test_init(); grpc_op ops[6]; diff --git a/test/core/bad_ssl/generate_tests.bzl b/test/core/bad_ssl/generate_tests.bzl index 3ce7de49171..ddd3b3c97bf 100755 --- a/test/core/bad_ssl/generate_tests.bzl +++ b/test/core/bad_ssl/generate_tests.bzl @@ -35,6 +35,7 @@ def grpc_bad_ssl_tests(): hdrs = ["server_common.h"], external_deps = [ "absl/log:check", + "absl/log:log", ], deps = [ "//test/core/test_util:grpc_test_util", diff --git a/test/core/bad_ssl/server_common.cc b/test/core/bad_ssl/server_common.cc index 1f9c0a69f5f..e76708b1969 100644 --- a/test/core/bad_ssl/server_common.cc +++ b/test/core/bad_ssl/server_common.cc @@ -21,8 +21,8 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" -#include #include #include "test/core/test_util/cmdline.h" @@ -74,7 +74,7 @@ void bad_ssl_run(grpc_server* server) { signal(SIGINT, sigint_handler); while (!shutdown_finished) { if (got_sigint && !shutdown_started) { - gpr_log(GPR_INFO, "Shutting down due to SIGINT"); + LOG(INFO) << "Shutting down due to SIGINT"; shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); grpc_server_shutdown_and_notify(server, shutdown_cq, nullptr); CHECK(grpc_completion_queue_pluck(shutdown_cq, nullptr, diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index 10831f5090c..b54cc023fa3 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -37,6 +37,7 @@ grpc_cc_test( srcs = ["channel_args_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], language = "C++", @@ -149,6 +150,7 @@ grpc_cc_test( name = "metrics_test", srcs = ["metrics_test.cc"], external_deps = [ + "absl/log:log", "gtest", ], language = "C++", diff --git a/test/core/channel/channel_args_test.cc b/test/core/channel/channel_args_test.cc index 3e59d01bfa0..1fe9f0937b1 100644 --- a/test/core/channel/channel_args_test.cc +++ b/test/core/channel/channel_args_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "gtest/gtest.h" #include @@ -28,7 +29,6 @@ #include #include #include -#include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/gprpp/notification.h" @@ -272,7 +272,7 @@ struct fake_class { }; static void* fake_pointer_arg_copy(void* arg) { - gpr_log(GPR_DEBUG, "fake_pointer_arg_copy"); + VLOG(2) << "fake_pointer_arg_copy"; fake_class* fc = static_cast(arg); fake_class* new_fc = static_cast(gpr_malloc(sizeof(fake_class))); new_fc->foo = fc->foo; @@ -280,7 +280,7 @@ static void* fake_pointer_arg_copy(void* arg) { } static void fake_pointer_arg_destroy(void* arg) { - gpr_log(GPR_DEBUG, "fake_pointer_arg_destroy"); + VLOG(2) << "fake_pointer_arg_destroy"; fake_class* fc = static_cast(arg); gpr_free(fc); } diff --git a/test/core/channel/metrics_test.cc b/test/core/channel/metrics_test.cc index d6b4d04d17c..3d57b32d2ab 100644 --- a/test/core/channel/metrics_test.cc +++ b/test/core/channel/metrics_test.cc @@ -16,10 +16,7 @@ #include -#include "absl/container/flat_hash_map.h" -#include "absl/strings/match.h" -#include "absl/strings/str_cat.h" -#include "absl/strings/str_join.h" +#include "absl/log/log.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -40,15 +37,15 @@ class MetricsTest : public ::testing::Test { }; TEST_F(MetricsTest, UInt64Counter) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; - auto uint64_counter_handle = GlobalInstrumentsRegistry::RegisterUInt64Counter( - "uint64_counter", "A simple uint64 counter.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + auto uint64_counter_handle = + GlobalInstrumentsRegistry::RegisterUInt64Counter( + "uint64_counter", "A simple uint64 counter.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -58,34 +55,37 @@ TEST_F(MetricsTest, UInt64Counter) { auto plugin3 = MakeStatsPluginForTarget(kDomain3To4); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")) - .AddCounter(uint64_counter_handle, 1, kLabelValues, kOptionalLabelValues); + .AddCounter(uint64_counter_handle, uint64_t(1), kLabelValues, + kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")) - .AddCounter(uint64_counter_handle, 2, kLabelValues, kOptionalLabelValues); + .AddCounter(uint64_counter_handle, uint64_t(2), kLabelValues, + kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")) - .AddCounter(uint64_counter_handle, 3, kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetCounterValue(uint64_counter_handle, kLabelValues, - kOptionalLabelValues), + .AddCounter(uint64_counter_handle, uint64_t(3), kLabelValues, + kOptionalLabelValues); + EXPECT_THAT(plugin1->GetUInt64CounterValue( + uint64_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1)); - EXPECT_THAT(plugin2->GetCounterValue(uint64_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetUInt64CounterValue( + uint64_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin3->GetCounterValue(uint64_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetUInt64CounterValue( + uint64_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(6)); } TEST_F(MetricsTest, DoubleCounter) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; - auto double_counter_handle = GlobalInstrumentsRegistry::RegisterDoubleCounter( - "double_counter", "A simple double counter.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + auto double_counter_handle = + GlobalInstrumentsRegistry::RegisterDoubleCounter( + "double_counter", "A simple double counter.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -105,28 +105,27 @@ TEST_F(MetricsTest, DoubleCounter) { StatsPluginChannelScope(kDomain3To4, "")) .AddCounter(double_counter_handle, 3.45, kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetCounterValue(double_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCounterValue( + double_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1.23)); - EXPECT_THAT(plugin2->GetCounterValue(double_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCounterValue( + double_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.57)); - EXPECT_THAT(plugin3->GetCounterValue(double_counter_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetDoubleCounterValue( + double_counter_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(7.02)); } TEST_F(MetricsTest, UInt64Histogram) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto uint64_histogram_handle = GlobalInstrumentsRegistry::RegisterUInt64Histogram( - "uint64_histogram", "A simple uint64 histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "uint64_histogram", "A simple uint64 histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -136,38 +135,37 @@ TEST_F(MetricsTest, UInt64Histogram) { auto plugin3 = MakeStatsPluginForTarget(kDomain3To4); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")) - .RecordHistogram(uint64_histogram_handle, 1, kLabelValues, + .RecordHistogram(uint64_histogram_handle, uint64_t(1), kLabelValues, kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")) - .RecordHistogram(uint64_histogram_handle, 2, kLabelValues, + .RecordHistogram(uint64_histogram_handle, uint64_t(2), kLabelValues, kOptionalLabelValues); GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")) - .RecordHistogram(uint64_histogram_handle, 3, kLabelValues, + .RecordHistogram(uint64_histogram_handle, uint64_t(3), kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetHistogramValue(uint64_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetUInt64HistogramValue( + uint64_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1))); - EXPECT_THAT(plugin2->GetHistogramValue(uint64_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetUInt64HistogramValue( + uint64_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1, 2))); - EXPECT_THAT(plugin3->GetHistogramValue(uint64_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetUInt64HistogramValue( + uint64_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1, 2, 3))); } TEST_F(MetricsTest, DoubleHistogram) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto double_histogram_handle = GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "double_histogram", "A simple double histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -187,31 +185,30 @@ TEST_F(MetricsTest, DoubleHistogram) { StatsPluginChannelScope(kDomain3To4, "")) .RecordHistogram(double_histogram_handle, 3.45, kLabelValues, kOptionalLabelValues); - EXPECT_THAT(plugin1->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleHistogramValue( + double_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1.23))); - EXPECT_THAT(plugin2->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleHistogramValue( + double_histogram_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34))); EXPECT_THAT( - plugin3->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + plugin3->GetDoubleHistogramValue(double_histogram_handle, kLabelValues, + kOptionalLabelValues), ::testing::Optional(::testing::UnorderedElementsAre(1.23, 2.34, 3.45))); } TEST_F(MetricsTest, Int64CallbackGauge) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto int64_gauge_handle = GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( - "int64_gauge", "A simple int64 gauge.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kLabelValues2[] = {"label_value_3", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "int64_gauge", "A simple int64 gauge.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kLabelValues2 = {"label_value_3", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -221,184 +218,184 @@ TEST_F(MetricsTest, Int64CallbackGauge) { auto plugin3 = MakeStatsPluginForTarget(kDomain1To4); // Register two callbacks that set the same metric but with different // label values. The callbacks get used only by plugin1. - gpr_log(GPR_INFO, "testing callbacks for: plugin1"); + LOG(INFO) << "testing callbacks for: plugin1"; auto group1 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")); auto callback1 = group1.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 1, kLabelValues, + reporter.Report(int64_gauge_handle, int64_t(1), kLabelValues, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); auto callback2 = group1.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 2, kLabelValues2, + reporter.Report(int64_gauge_handle, int64_t(2), kLabelValues2, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); // No plugins have data yet. - EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 should have data, but the others should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); callback2.reset(); // Now register callbacks that hit both plugin1 and plugin2. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2"; auto group2 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")); callback1 = group2.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 3, kLabelValues, + reporter.Report(int64_gauge_handle, int64_t(3), kLabelValues, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); callback2 = group2.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 4, kLabelValues2, + reporter.Report(int64_gauge_handle, int64_t(4), kLabelValues2, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); // Plugin1 still has data from before, but the others have none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); callback2.reset(); // Now register callbacks that hit all three plugins. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2, plugin3"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2, plugin3"; auto group3 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")); callback1 = group3.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 5, kLabelValues, + reporter.Report(int64_gauge_handle, int64_t(5), kLabelValues, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); callback2 = group3.RegisterCallback( [&](CallbackMetricReporter& reporter) { - reporter.Report(int64_gauge_handle, 6, kLabelValues2, + reporter.Report(int64_gauge_handle, int64_t(6), kLabelValues2, kOptionalLabelValues); }, - {int64_gauge_handle}); + Duration::Seconds(5), int64_gauge_handle); // Plugin1 and plugin2 still has data from before, but plugin3 has none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(int64_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetInt64CallbackGaugeValue( + int64_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6)); // Need to destroy callbacks before the plugin group that created them. callback1.reset(); @@ -406,18 +403,17 @@ TEST_F(MetricsTest, Int64CallbackGauge) { } TEST_F(MetricsTest, DoubleCallbackGauge) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto double_gauge_handle = GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( - "double_gauge", "A simple double gauge.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kLabelValues2[] = {"label_value_3", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "double_gauge", "A simple double gauge.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kLabelValues2 = {"label_value_3", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; constexpr absl::string_view kDomain2To4 = "domain2.domain3.domain4"; @@ -427,7 +423,7 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { auto plugin3 = MakeStatsPluginForTarget(kDomain1To4); // Register two callbacks that set the same metric but with different // label values. The callbacks get used only by plugin1. - gpr_log(GPR_INFO, "testing callbacks for: plugin1"); + LOG(INFO) << "testing callbacks for: plugin1"; auto group1 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain3To4, "")); auto callback1 = group1.RegisterCallback( @@ -435,60 +431,60 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { reporter.Report(double_gauge_handle, 1.23, kLabelValues, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); auto callback2 = group1.RegisterCallback( [&](CallbackMetricReporter& reporter) { reporter.Report(double_gauge_handle, 2.34, kLabelValues2, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); // No plugins have data yet. - EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 should have data, but the others should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1.23)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2.34)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); callback2.reset(); // Now register callbacks that hit both plugin1 and plugin2. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2"; auto group2 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain2To4, "")); callback1 = group2.RegisterCallback( @@ -496,60 +492,60 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { reporter.Report(double_gauge_handle, 3.45, kLabelValues, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); callback2 = group2.RegisterCallback( [&](CallbackMetricReporter& reporter) { reporter.Report(double_gauge_handle, 4.56, kLabelValues2, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); // Plugin1 still has data from before, but the others have none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(1.23)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(2.34)); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // De-register the callbacks. callback1.reset(); callback2.reset(); // Now register callbacks that hit all three plugins. - gpr_log(GPR_INFO, "testing callbacks for: plugin1, plugin2, plugin3"); + LOG(INFO) << "testing callbacks for: plugin1, plugin2, plugin3"; auto group3 = GlobalStatsPluginRegistry::GetStatsPluginsForChannel( StatsPluginChannelScope(kDomain1To4, "")); callback1 = group3.RegisterCallback( @@ -557,54 +553,54 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { reporter.Report(double_gauge_handle, 5.67, kLabelValues, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); callback2 = group3.RegisterCallback( [&](CallbackMetricReporter& reporter) { reporter.Report(double_gauge_handle, 6.78, kLabelValues2, kOptionalLabelValues); }, - {double_gauge_handle}); + Duration::Seconds(5), double_gauge_handle); // Plugin1 and plugin2 still has data from before, but plugin3 has none. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(3.45)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(4.56)); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), absl::nullopt); - EXPECT_EQ(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_EQ(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), absl::nullopt); // Now invoke the callbacks. plugin1->TriggerCallbacks(); plugin2->TriggerCallbacks(); plugin3->TriggerCallbacks(); // Now plugin1 and plugin2 should have data, but plugin3 should not. - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5.67)); - EXPECT_THAT(plugin1->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin1->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6.78)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5.67)); - EXPECT_THAT(plugin2->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin2->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6.78)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues, kOptionalLabelValues), ::testing::Optional(5.67)); - EXPECT_THAT(plugin3->GetCallbackGaugeValue(double_gauge_handle, kLabelValues2, - kOptionalLabelValues), + EXPECT_THAT(plugin3->GetDoubleCallbackGaugeValue( + double_gauge_handle, kLabelValues2, kOptionalLabelValues), ::testing::Optional(6.78)); // Need to destroy callbacks before the plugin group that created them. callback1.reset(); @@ -612,16 +608,15 @@ TEST_F(MetricsTest, DoubleCallbackGauge) { } TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; auto double_histogram_handle = GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/false); - constexpr absl::string_view kLabelValues[] = {"label_value_1", - "label_value_2"}; - constexpr absl::string_view kOptionalLabelValues[] = { + "double_histogram", "A simple double histogram.", "unit", false) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + std::array kLabelValues = {"label_value_1", + "label_value_2"}; + std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; constexpr absl::string_view kDomain1To4 = "domain1.domain2.domain3.domain4"; auto plugin = MakeStatsPluginForTarget(kDomain1To4); @@ -629,24 +624,26 @@ TEST_F(MetricsTest, DisableByDefaultMetricIsNotRecordedByFakeStatsPlugin) { StatsPluginChannelScope(kDomain1To4, "")) .RecordHistogram(double_histogram_handle, 1.23, kLabelValues, kOptionalLabelValues); - EXPECT_EQ(plugin->GetHistogramValue(double_histogram_handle, kLabelValues, - kOptionalLabelValues), + EXPECT_EQ(plugin->GetDoubleHistogramValue(double_histogram_handle, + kLabelValues, kOptionalLabelValues), absl::nullopt); } using MetricsDeathTest = MetricsTest; TEST_F(MetricsDeathTest, RegisterTheSameMetricNameWouldCrash) { - const absl::string_view kLabelKeys[] = {"label_key_1", "label_key_2"}; - const absl::string_view kOptionalLabelKeys[] = {"optional_label_key_1", - "optional_label_key_2"}; (void)GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, true); - EXPECT_DEATH(GlobalInstrumentsRegistry::RegisterDoubleHistogram( - "double_histogram", "A simple double histogram.", "unit", - kLabelKeys, kOptionalLabelKeys, true), - "Metric name double_histogram has already been registered."); + "double_histogram", "A simple double histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(); + EXPECT_DEATH( + GlobalInstrumentsRegistry::RegisterDoubleHistogram( + "double_histogram", "A simple double histogram.", "unit", true) + .Labels("label_key_1", "label_key_2") + .OptionalLabels("optional_label_key_1", "optional_label_key_2") + .Build(), + "Metric name double_histogram has already been registered."); } } // namespace diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD index d6825f63e41..21746ffd776 100644 --- a/test/core/compression/BUILD +++ b/test/core/compression/BUILD @@ -26,7 +26,10 @@ licenses(["notice"]) grpc_cc_test( name = "compression_test", srcs = ["compression_test.cc"], - external_deps = ["gtest"], + external_deps = [ + "absl/log:log", + "gtest", + ], language = "C++", uses_event_engine = False, uses_polling = False, @@ -67,7 +70,10 @@ grpc_fuzzer( grpc_cc_test( name = "message_compress_test", srcs = ["message_compress_test.cc"], - external_deps = ["gtest"], + external_deps = [ + "absl/log:log", + "gtest", + ], language = "C++", uses_event_engine = False, uses_polling = False, diff --git a/test/core/compression/compression_test.cc b/test/core/compression/compression_test.cc index 2297e5c8303..569a1d7e2ff 100644 --- a/test/core/compression/compression_test.cc +++ b/test/core/compression/compression_test.cc @@ -21,11 +21,11 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include #include -#include #include "src/core/lib/gpr/useful.h" #include "test/core/test_util/test_config.h" @@ -40,7 +40,7 @@ TEST(CompressionTest, CompressionAlgorithmParse) { }; const char* invalid_names[] = {"gzip2", "foo", "", "2gzip"}; - gpr_log(GPR_DEBUG, "test_compression_algorithm_parse"); + VLOG(2) << "test_compression_algorithm_parse"; for (i = 0; i < GPR_ARRAY_SIZE(valid_names); i++) { const char* valid_name = valid_names[i]; @@ -73,7 +73,7 @@ TEST(CompressionTest, CompressionAlgorithmName) { GRPC_COMPRESS_DEFLATE, }; - gpr_log(GPR_DEBUG, "test_compression_algorithm_name"); + VLOG(2) << "test_compression_algorithm_name"; for (i = 0; i < GPR_ARRAY_SIZE(valid_algorithms); i++) { success = grpc_compression_algorithm_name(valid_algorithms[i], &name); @@ -88,7 +88,7 @@ TEST(CompressionTest, CompressionAlgorithmName) { } TEST(CompressionTest, CompressionAlgorithmForLevel) { - gpr_log(GPR_DEBUG, "test_compression_algorithm_for_level"); + VLOG(2) << "test_compression_algorithm_for_level"; { // accept only identity (aka none) @@ -211,7 +211,7 @@ TEST(CompressionTest, CompressionEnableDisableAlgorithm) { grpc_compression_options options; grpc_compression_algorithm algorithm; - gpr_log(GPR_DEBUG, "test_compression_enable_disable_algorithm"); + VLOG(2) << "test_compression_enable_disable_algorithm"; grpc_compression_options_init(&options); for (algorithm = GRPC_COMPRESS_NONE; diff --git a/test/core/compression/message_compress_test.cc b/test/core/compression/message_compress_test.cc index b3cf8ba7e47..5666ed3e477 100644 --- a/test/core/compression/message_compress_test.cc +++ b/test/core/compression/message_compress_test.cc @@ -28,7 +28,6 @@ #include #include -#include #include "src/core/lib/gpr/useful.h" #include "src/core/lib/iomgr/exec_ctx.h" diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 08c373e425d..597fb7c0c26 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -28,6 +28,7 @@ grpc_cc_library( "absl/container:flat_hash_map", "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/strings", "absl/strings:str_format", "absl/types:variant", @@ -64,6 +65,7 @@ grpc_cc_library( hdrs = ["fixtures/http_proxy_fixture.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -96,7 +98,10 @@ grpc_cc_library( name = "proxy", srcs = ["fixtures/proxy.cc"], hdrs = ["fixtures/proxy.h"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "//:channel_arg_names", @@ -120,6 +125,7 @@ grpc_cc_library( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/memory", "absl/meta:type_traits", "absl/random", @@ -500,7 +506,10 @@ grpc_core_end2end_test(name = "write_buffering_at_end") grpc_cc_test( name = "bad_server_response_test", srcs = ["bad_server_response_test.cc"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "cq_verifier", @@ -523,7 +532,10 @@ grpc_cc_test( grpc_cc_test( name = "connection_refused_test", srcs = ["connection_refused_test.cc"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "cq_verifier", @@ -541,6 +553,7 @@ grpc_cc_test( srcs = ["dualstack_socket_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status:statusor", "absl/strings", "absl/strings:str_format", @@ -565,6 +578,7 @@ grpc_cc_test( srcs = ["goaway_server_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/strings", @@ -596,7 +610,10 @@ grpc_cc_test( grpc_cc_test( name = "invalid_call_argument_test", srcs = ["invalid_call_argument_test.cc"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], language = "C++", deps = [ "cq_verifier", @@ -623,6 +640,7 @@ grpc_cc_test( srcs = ["no_server_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/status", "absl/status:statusor", "absl/time", @@ -652,6 +670,7 @@ grpc_cc_test( external_deps = [ "absl/functional:any_invocable", "absl/log:check", + "absl/log:log", "absl/memory", "absl/meta:type_traits", "absl/strings", diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc index eb9b0c09a2f..b2c38dba64a 100644 --- a/test/core/end2end/bad_server_response_test.cc +++ b/test/core/end2end/bad_server_response_test.cc @@ -25,6 +25,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -35,7 +36,6 @@ #include #include #include -#include #include #include @@ -135,8 +135,7 @@ static void handle_write() { static void handle_read(void* /*arg*/, grpc_error_handle error) { if (!error.ok()) { - gpr_log(GPR_ERROR, "handle_read error: %s", - grpc_core::StatusToString(error).c_str()); + LOG(ERROR) << "handle_read error: " << grpc_core::StatusToString(error); return; } state.incoming_data_length += state.temp_incoming_buffer.length; @@ -145,15 +144,13 @@ static void handle_read(void* /*arg*/, grpc_error_handle error) { for (i = 0; i < state.temp_incoming_buffer.count; i++) { char* dump = grpc_dump_slice(state.temp_incoming_buffer.slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); - gpr_log(GPR_DEBUG, "Server received: %s", dump); + VLOG(2) << "Server received: " << dump; gpr_free(dump); } - gpr_log(GPR_DEBUG, - "got %" PRIuPTR " bytes, expected %" PRIuPTR - " bytes or a non-HTTP2 response to be sent", - state.incoming_data_length, - SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD); + VLOG(2) << "got " << state.incoming_data_length << " bytes, expected " + << SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD + << " bytes or a non-HTTP2 response to be sent"; if (state.incoming_data_length >= SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD || !state.http2_response) { @@ -299,8 +296,8 @@ static void actually_poll_server(void* arg) { bool done = gpr_atm_acq_load(&state.done_atm) != 0; gpr_timespec time_left = gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME)); - gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done, - time_left.tv_sec, time_left.tv_nsec); + VLOG(2) << "done=" << done << ", time_left=" << time_left.tv_sec << "." + << time_left.tv_nsec; if (done || gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) < 0) { break; } diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc index 055e115a286..1e3414b8875 100644 --- a/test/core/end2end/connection_refused_test.cc +++ b/test/core/end2end/connection_refused_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include "src/core/lib/channel/channel_args.h" @@ -49,8 +49,8 @@ static void run_test(bool wait_for_ready, bool use_service_config) { grpc_status_code status; grpc_slice details; - gpr_log(GPR_INFO, "TEST: wait_for_ready=%d use_service_config=%d", - wait_for_ready, use_service_config); + LOG(INFO) << "TEST: wait_for_ready=" << wait_for_ready + << " use_service_config=" << use_service_config; grpc_init(); @@ -81,7 +81,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) { // create a call, channel to a port which will refuse connection int port = grpc_pick_unused_port_or_die(); std::string addr = grpc_core::JoinHostPort("127.0.0.1", port); - gpr_log(GPR_INFO, "server: %s", addr.c_str()); + LOG(INFO) << "server: " << addr; grpc_channel_credentials* creds = grpc_insecure_credentials_create(); chan = grpc_channel_create(addr.c_str(), creds, args); grpc_channel_credentials_release(creds); diff --git a/test/core/end2end/cq_verifier.cc b/test/core/end2end/cq_verifier.cc index c318f7fa301..c0bc5b66f97 100644 --- a/test/core/end2end/cq_verifier.cc +++ b/test/core/end2end/cq_verifier.cc @@ -29,6 +29,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/escaping.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -41,7 +42,6 @@ #include #include #include -#include #include #include "src/core/lib/compression/message_compress.h" @@ -126,9 +126,8 @@ int raw_byte_buffer_eq_slice(grpc_byte_buffer* rbb, grpc_slice b) { 0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), GRPC_SLICE_LENGTH(a)); if (!ok) { - gpr_log(GPR_ERROR, - "SLICE MISMATCH: left_length=%" PRIuPTR " right_length=%" PRIuPTR, - GRPC_SLICE_LENGTH(a), GRPC_SLICE_LENGTH(b)); + LOG(ERROR) << "SLICE MISMATCH: left_length=" << GRPC_SLICE_LENGTH(a) + << " right_length=" << GRPC_SLICE_LENGTH(b); std::string out; const char* a_str = reinterpret_cast(GRPC_SLICE_START_PTR(a)); const char* b_str = reinterpret_cast(GRPC_SLICE_START_PTR(b)); @@ -151,7 +150,7 @@ int raw_byte_buffer_eq_slice(grpc_byte_buffer* rbb, grpc_slice b) { absl::CEscape(absl::string_view(&b_str[i], 1)), "\u001b[0m"); } - gpr_log(GPR_ERROR, "%s", out.c_str()); + LOG(ERROR) << out; } } grpc_slice_unref(a); @@ -365,8 +364,7 @@ void CqVerifier::Verify(Duration timeout, SourceLocation location) { while (!expectations_.empty()) { must_log = std::exchange(added_expectations_, false) || must_log; if (log_verifications_ && must_log) { - gpr_log(GPR_ERROR, "Verify %s for %s", ToShortString().c_str(), - timeout.ToString().c_str()); + LOG(ERROR) << "Verify " << ToShortString() << " for " << timeout; } must_log = false; grpc_event ev = Step(deadline); @@ -423,8 +421,7 @@ bool CqVerifier::AllMaybes() const { void CqVerifier::VerifyEmpty(Duration timeout, SourceLocation location) { if (log_verifications_) { - gpr_log(GPR_ERROR, "Verify empty completion queue for %s", - timeout.ToString().c_str()); + LOG(ERROR) << "Verify empty completion queue for " << timeout; } const gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), timeout.as_timespec()); diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc index bf793e97bec..33ab2091c1b 100644 --- a/test/core/end2end/dualstack_socket_test.cc +++ b/test/core/end2end/dualstack_socket_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/statusor.h" #include @@ -47,7 +48,6 @@ #include #include #include -#include #include "src/core/lib/address_utils/sockaddr_utils.h" #include "src/core/lib/gprpp/host_port.h" @@ -78,7 +78,7 @@ static void log_resolved_addrs(const char* label, const char* hostname) { return; } for (const auto& addr : *addresses_or) { - gpr_log(GPR_INFO, "%s: %s", label, grpc_sockaddr_to_uri(&addr)->c_str()); + LOG(INFO) << label << ": " << grpc_sockaddr_to_uri(&addr)->c_str(); } } @@ -152,9 +152,9 @@ void test_connect(const char* server_host, const char* client_host, int port, client = grpc_channel_create(client_hostport.c_str(), creds, nullptr); grpc_channel_credentials_release(creds); - gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)", - server_hostport.c_str(), client_hostport.c_str(), - expect_ok ? "success" : "failure"); + LOG(INFO) << "Testing with server=" << server_hostport.c_str() + << " client=" << client_hostport.c_str() << " (expecting " + << (expect_ok ? "success" : "failure") << ")"; log_resolved_addrs("server resolved addr", server_host); log_resolved_addrs("client resolved addr", client_host); @@ -236,7 +236,7 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv.Verify(); peer = grpc_call_get_peer(c); - gpr_log(GPR_DEBUG, "got peer: '%s'", peer); + VLOG(2) << "got peer: '" << peer << "'"; gpr_free(peer); CHECK_EQ(status, GRPC_STATUS_UNIMPLEMENTED); @@ -251,8 +251,8 @@ void test_connect(const char* server_host, const char* client_host, int port, cqv.Expect(grpc_core::CqVerifier::tag(1), true); cqv.Verify(); - gpr_log(GPR_INFO, "status: %d (expected: %d)", status, - GRPC_STATUS_UNAVAILABLE); + LOG(INFO) << "status: " << status + << " (expected: " << GRPC_STATUS_UNAVAILABLE << ")"; CHECK_EQ(status, GRPC_STATUS_UNAVAILABLE); } @@ -301,10 +301,9 @@ int external_dns_works(const char* host) { // dualstack_socket_test from functioning correctly). See b/201064791. if (grpc_sockaddr_to_uri(&addr).value() == "ipv6:%5B64:ff9b::7f00:1%5D:80") { - gpr_log( - GPR_INFO, - "Detected DNS64 server response. Tests that depend on " - "*.unittest.grpc.io. will be skipped as they won't work with DNS64."); + LOG(INFO) << "Detected DNS64 server response. Tests that depend on " + "*.unittest.grpc.io. will be skipped as they won't work " + "with DNS64."; result = 0; break; } @@ -319,7 +318,7 @@ int main(int argc, char** argv) { grpc_init(); if (!grpc_ipv6_loopback_available()) { - gpr_log(GPR_INFO, "Can't bind to ::1. Skipping IPv6 tests."); + LOG(INFO) << "Can't bind to ::1. Skipping IPv6 tests."; do_ipv6 = 0; } @@ -360,7 +359,7 @@ int main(int argc, char** argv) { if (!external_dns_works("loopback4.unittest.grpc.io") || !external_dns_works("loopback46.unittest.grpc.io")) { - gpr_log(GPR_INFO, "Skipping tests that depend on *.unittest.grpc.io."); + LOG(INFO) << "Skipping tests that depend on *.unittest.grpc.io."; } else { test_connect("loopback46.unittest.grpc.io", "loopback4.unittest.grpc.io", 0, 1); diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index 30615b1698a..51505c91fd5 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -23,6 +23,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/random/random.h" @@ -117,7 +118,7 @@ void CoreEnd2endTest::TearDown() { // This will wait until gRPC shutdown has actually happened to make sure // no gRPC resources (such as thread) are active. (timeout = 10s) if (!grpc_wait_until_shutdown(10)) { - gpr_log(GPR_ERROR, "Timeout in waiting for gRPC shutdown"); + LOG(ERROR) << "Timeout in waiting for gRPC shutdown"; } } CHECK_EQ(client_, nullptr); @@ -153,8 +154,8 @@ std::string CoreEnd2endTest::IncomingMessage::payload() const { grpc_slice_buffer decompressed_buffer; grpc_slice_buffer_init(&decompressed_buffer); CHECK(grpc_msg_decompress(payload_->data.raw.compression, - &payload_->data.raw.slice_buffer, - &decompressed_buffer)); + &payload_->data.raw.slice_buffer, + &decompressed_buffer)); grpc_byte_buffer* rbb = grpc_raw_byte_buffer_create( decompressed_buffer.slices, decompressed_buffer.count); grpc_byte_buffer_reader reader; diff --git a/test/core/end2end/fixtures/http_proxy_fixture.cc b/test/core/end2end/fixtures/http_proxy_fixture.cc index be2ec412014..3eca777e098 100644 --- a/test/core/end2end/fixtures/http_proxy_fixture.cc +++ b/test/core/end2end/fixtures/http_proxy_fixture.cc @@ -27,6 +27,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/escaping.h" @@ -37,7 +38,6 @@ #include #include #include -#include #include #include "src/core/lib/address_utils/sockaddr_utils.h" @@ -510,8 +510,8 @@ static bool proxy_auth_header_matches(absl::string_view proxy_auth_header_val, // which will cause the client connection to be dropped. static void on_read_request_done_locked(void* arg, grpc_error_handle error) { proxy_connection* conn = static_cast(arg); - gpr_log(GPR_DEBUG, "on_read_request_done: %p %s", conn, - grpc_core::StatusToString(error).c_str()); + VLOG(2) << "on_read_request_done: " << conn << " " + << grpc_core::StatusToString(error); if (!error.ok()) { proxy_connection_failed(conn, SETUP_FAILED, "HTTP proxy read request", error); @@ -670,7 +670,7 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create( // Construct proxy address. const int proxy_port = grpc_pick_unused_port_or_die(); proxy->proxy_name = grpc_core::JoinHostPort("localhost", proxy_port); - gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name.c_str()); + LOG(INFO) << "Proxy address: " << proxy->proxy_name; // Create TCP server. auto channel_args = grpc_core::CoreConfiguration::Get() .channel_args_preconditioning() diff --git a/test/core/end2end/fixtures/proxy.cc b/test/core/end2end/fixtures/proxy.cc index cb1a2e04cb2..febdb809838 100644 --- a/test/core/end2end/fixtures/proxy.cc +++ b/test/core/end2end/fixtures/proxy.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -31,7 +32,6 @@ #include #include #include -#include #include #include @@ -106,8 +106,8 @@ grpc_end2end_proxy* grpc_end2end_proxy_create( proxy->proxy_port = grpc_core::JoinHostPort("localhost", proxy_port); proxy->server_port = grpc_core::JoinHostPort("localhost", server_port); - gpr_log(GPR_DEBUG, "PROXY ADDR:%s BACKEND:%s", proxy->proxy_port.c_str(), - proxy->server_port.c_str()); + VLOG(2) << "PROXY ADDR:" << proxy->proxy_port + << " BACKEND:" << proxy->server_port; proxy->cq = grpc_completion_queue_create_for_next(nullptr); proxy->server = def->create_server(proxy->proxy_port.c_str(), server_args); diff --git a/test/core/end2end/fuzzers/BUILD b/test/core/end2end/fuzzers/BUILD index 35f52f6be3b..c3a1f0245c9 100644 --- a/test/core/end2end/fuzzers/BUILD +++ b/test/core/end2end/fuzzers/BUILD @@ -36,6 +36,7 @@ grpc_cc_library( hdrs = ["fuzzing_common.h"], external_deps = [ "absl/log:check", + "absl/log:log", "absl/strings", ], deps = [ @@ -92,6 +93,7 @@ grpc_cc_library( name = "network_input", srcs = ["network_input.cc"], hdrs = ["network_input.h"], + external_deps = ["absl/log:log"], deps = [ "fuzzer_input_proto", "//:chttp2_frame", diff --git a/test/core/end2end/fuzzers/fuzzing_common.cc b/test/core/end2end/fuzzers/fuzzing_common.cc index 4a20a7870fe..2597694bf3b 100644 --- a/test/core/end2end/fuzzers/fuzzing_common.cc +++ b/test/core/end2end/fuzzers/fuzzing_common.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/types/optional.h" @@ -638,7 +639,7 @@ bool BasicFuzzer::Continue() { BasicFuzzer::Result BasicFuzzer::ExecuteAction( const api_fuzzer::Action& action) { - gpr_log(GPR_DEBUG, "EXECUTE_ACTION: %s", action.DebugString().c_str()); + VLOG(2) << "EXECUTE_ACTION: " << action.DebugString(); switch (action.type_case()) { case api_fuzzer::Action::TYPE_NOT_SET: return BasicFuzzer::Result::kFailed; diff --git a/test/core/end2end/fuzzers/network_input.cc b/test/core/end2end/fuzzers/network_input.cc index 855d3185678..278fd0ffc69 100644 --- a/test/core/end2end/fuzzers/network_input.cc +++ b/test/core/end2end/fuzzers/network_input.cc @@ -23,6 +23,7 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/string_view.h" #include "absl/types/span.h" @@ -520,8 +521,7 @@ Duration ScheduleConnection( endpoint) mutable { ExecCtx exec_ctx; if (!endpoint.ok()) { - gpr_log(GPR_ERROR, "Failed to connect: %s", - endpoint.status().ToString().c_str()); + LOG(ERROR) << "Failed to connect: " << endpoint.status(); return; } std::shared_ptr ep = diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 3efd3939364..edf58074223 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -27,6 +27,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" @@ -40,7 +41,6 @@ #include #include #include -#include #include #include @@ -212,9 +212,8 @@ static void my_cancel_ares_request(grpc_ares_request* request) { int main(int argc, char** argv) { // TODO(yijiem): rewrite this test with a custom EventEngine DNS Resolver if (grpc_core::IsEventEngineDnsEnabled()) { - gpr_log( - GPR_ERROR, - "Skipping iomgr-specific DNS test because EventEngine DNS is enabled"); + LOG(ERROR) << "Skipping iomgr-specific DNS test because EventEngine DNS is " + "enabled"; return 0; } grpc_completion_queue* cq; diff --git a/test/core/end2end/grpc_core_end2end_test.bzl b/test/core/end2end/grpc_core_end2end_test.bzl index 78733efcf2b..8b75ae6aac8 100644 --- a/test/core/end2end/grpc_core_end2end_test.bzl +++ b/test/core/end2end/grpc_core_end2end_test.bzl @@ -43,6 +43,9 @@ def grpc_core_end2end_test(name, shard_count = 10, tags = []): srcs = [ "tests/%s.cc" % name, ], + external_deps = [ + "absl/log:log", + ], deps = [ "cq_verifier", "end2end_test_lib", diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc index d24c6956235..3d1470194ec 100644 --- a/test/core/end2end/h2_ssl_cert_test.cc +++ b/test/core/end2end/h2_ssl_cert_test.cc @@ -25,6 +25,7 @@ #include "absl/functional/any_invocable.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/types/optional.h" #include "gtest/gtest.h" @@ -37,7 +38,6 @@ #include #include #include -#include #include #include "src/core/lib/channel/channel_args.h" @@ -245,9 +245,7 @@ static void simple_request_body(grpc_core::CoreTestFixture* f, class H2SslCertTest : public ::testing::TestWithParam { protected: - H2SslCertTest() { - gpr_log(GPR_INFO, "SSL_CERT_tests/%s", GetParam().config.name); - } + H2SslCertTest() { LOG(INFO) << "SSL_CERT_tests/" << GetParam().config.name; } void SetUp() override { fixture_ = GetParam().config.create_fixture(grpc_core::ChannelArgs(), grpc_core::ChannelArgs()); diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc index a297eb61a3b..1f086c3f98a 100644 --- a/test/core/end2end/invalid_call_argument_test.cc +++ b/test/core/end2end/invalid_call_argument_test.cc @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include #include @@ -32,7 +33,6 @@ #include #include #include -#include #include #include @@ -155,7 +155,7 @@ static void cleanup_test() { } static void test_non_null_reserved_on_start_batch() { - gpr_log(GPR_INFO, "test_non_null_reserved_on_start_batch"); + LOG(INFO) << "test_non_null_reserved_on_start_batch"; prepare_test(1); CHECK(GRPC_CALL_ERROR == @@ -165,7 +165,7 @@ static void test_non_null_reserved_on_start_batch() { } static void test_non_null_reserved_on_op() { - gpr_log(GPR_INFO, "test_non_null_reserved_on_op"); + LOG(INFO) << "test_non_null_reserved_on_op"; grpc_op* op; prepare_test(1); @@ -184,7 +184,7 @@ static void test_non_null_reserved_on_op() { } static void test_send_initial_metadata_more_than_once() { - gpr_log(GPR_INFO, "test_send_initial_metadata_more_than_once"); + LOG(INFO) << "test_send_initial_metadata_more_than_once"; grpc_op* op; prepare_test(1); @@ -216,7 +216,7 @@ static void test_send_initial_metadata_more_than_once() { } static void test_too_many_metadata() { - gpr_log(GPR_INFO, "test_too_many_metadata"); + LOG(INFO) << "test_too_many_metadata"; grpc_op* op; prepare_test(1); @@ -235,7 +235,7 @@ static void test_too_many_metadata() { } static void test_send_null_message() { - gpr_log(GPR_INFO, "test_send_null_message"); + LOG(INFO) << "test_send_null_message"; grpc_op* op; prepare_test(1); @@ -259,7 +259,7 @@ static void test_send_null_message() { } static void test_send_messages_at_the_same_time() { - gpr_log(GPR_INFO, "test_send_messages_at_the_same_time"); + LOG(INFO) << "test_send_messages_at_the_same_time"; grpc_op* op; grpc_slice request_payload_slice = @@ -293,7 +293,7 @@ static void test_send_messages_at_the_same_time() { } static void test_send_server_status_from_client() { - gpr_log(GPR_INFO, "test_send_server_status_from_client"); + LOG(INFO) << "test_send_server_status_from_client"; grpc_op* op; prepare_test(1); @@ -315,7 +315,7 @@ static void test_send_server_status_from_client() { } static void test_receive_initial_metadata_twice_at_client() { - gpr_log(GPR_INFO, "test_receive_initial_metadata_twice_at_client"); + LOG(INFO) << "test_receive_initial_metadata_twice_at_client"; grpc_op* op; prepare_test(1); @@ -347,7 +347,7 @@ static void test_receive_initial_metadata_twice_at_client() { } static void test_receive_message_with_invalid_flags() { - gpr_log(GPR_INFO, "test_receive_message_with_invalid_flags"); + LOG(INFO) << "test_receive_message_with_invalid_flags"; grpc_op* op; grpc_byte_buffer* payload = nullptr; @@ -366,7 +366,7 @@ static void test_receive_message_with_invalid_flags() { } static void test_receive_two_messages_at_the_same_time() { - gpr_log(GPR_INFO, "test_receive_two_messages_at_the_same_time"); + LOG(INFO) << "test_receive_two_messages_at_the_same_time"; grpc_op* op; grpc_byte_buffer* payload = nullptr; @@ -390,7 +390,7 @@ static void test_receive_two_messages_at_the_same_time() { } static void test_recv_close_on_server_from_client() { - gpr_log(GPR_INFO, "test_recv_close_on_server_from_client"); + LOG(INFO) << "test_recv_close_on_server_from_client"; grpc_op* op; prepare_test(1); @@ -409,7 +409,7 @@ static void test_recv_close_on_server_from_client() { } static void test_recv_status_on_client_twice() { - gpr_log(GPR_INFO, "test_recv_status_on_client_twice"); + LOG(INFO) << "test_recv_status_on_client_twice"; grpc_op* op; prepare_test(1); @@ -446,7 +446,7 @@ static void test_recv_status_on_client_twice() { } static void test_send_close_from_client_on_server() { - gpr_log(GPR_INFO, "test_send_close_from_client_on_server"); + LOG(INFO) << "test_send_close_from_client_on_server"; grpc_op* op; prepare_test(0); @@ -464,7 +464,7 @@ static void test_send_close_from_client_on_server() { } static void test_recv_status_on_client_from_server() { - gpr_log(GPR_INFO, "test_recv_status_on_client_from_server"); + LOG(INFO) << "test_recv_status_on_client_from_server"; grpc_op* op; prepare_test(0); @@ -486,7 +486,7 @@ static void test_recv_status_on_client_from_server() { } static void test_send_status_from_server_with_invalid_flags() { - gpr_log(GPR_INFO, "test_send_status_from_server_with_invalid_flags"); + LOG(INFO) << "test_send_status_from_server_with_invalid_flags"; grpc_op* op; prepare_test(0); @@ -508,7 +508,7 @@ static void test_send_status_from_server_with_invalid_flags() { } static void test_too_many_trailing_metadata() { - gpr_log(GPR_INFO, "test_too_many_trailing_metadata"); + LOG(INFO) << "test_too_many_trailing_metadata"; grpc_op* op; prepare_test(0); @@ -531,7 +531,7 @@ static void test_too_many_trailing_metadata() { } static void test_send_server_status_twice() { - gpr_log(GPR_INFO, "test_send_server_status_twice"); + LOG(INFO) << "test_send_server_status_twice"; grpc_op* op; prepare_test(0); @@ -560,7 +560,7 @@ static void test_send_server_status_twice() { } static void test_recv_close_on_server_with_invalid_flags() { - gpr_log(GPR_INFO, "test_recv_close_on_server_with_invalid_flags"); + LOG(INFO) << "test_recv_close_on_server_with_invalid_flags"; grpc_op* op; prepare_test(0); @@ -579,7 +579,7 @@ static void test_recv_close_on_server_with_invalid_flags() { } static void test_recv_close_on_server_twice() { - gpr_log(GPR_INFO, "test_recv_close_on_server_twice"); + LOG(INFO) << "test_recv_close_on_server_twice"; grpc_op* op; prepare_test(0); @@ -603,7 +603,7 @@ static void test_recv_close_on_server_twice() { } static void test_invalid_initial_metadata_reserved_key() { - gpr_log(GPR_INFO, "test_invalid_initial_metadata_reserved_key"); + LOG(INFO) << "test_invalid_initial_metadata_reserved_key"; grpc_metadata metadata; metadata.key = grpc_slice_from_static_string(":start_with_colon"); @@ -626,7 +626,7 @@ static void test_invalid_initial_metadata_reserved_key() { } static void test_multiple_ops_in_a_single_batch() { - gpr_log(GPR_INFO, "test_multiple_ops_in_a_single_batch"); + LOG(INFO) << "test_multiple_ops_in_a_single_batch"; grpc_op* op; prepare_test(1); diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc index dc3db4b37bf..4b14f0a1a72 100644 --- a/test/core/end2end/no_server_test.cc +++ b/test/core/end2end/no_server_test.cc @@ -21,6 +21,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/time/time.h" @@ -31,7 +32,6 @@ #include #include #include -#include #include #include "src/core/lib/channel/channel_args.h" @@ -45,7 +45,7 @@ #include "test/core/test_util/test_config.h" void run_test(bool wait_for_ready) { - gpr_log(GPR_INFO, "TEST: wait_for_ready=%d", wait_for_ready); + LOG(INFO) << "TEST: wait_for_ready=" << wait_for_ready; grpc_init(); @@ -104,7 +104,7 @@ void run_test(bool wait_for_ready) { cqv.Expect(grpc_core::CqVerifier::tag(1), true); cqv.Verify(); - gpr_log(GPR_INFO, "call status: %d", status); + LOG(INFO) << "call status: " << status; if (wait_for_ready) { CHECK_EQ(status, GRPC_STATUS_DEADLINE_EXCEEDED); } else { diff --git a/test/core/end2end/tests/call_creds.cc b/test/core/end2end/tests/call_creds.cc index ce6b949085f..2b078a1152d 100644 --- a/test/core/end2end/tests/call_creds.cc +++ b/test/core/end2end/tests/call_creds.cc @@ -18,6 +18,7 @@ #include +#include "absl/log/log.h" #include "absl/types/optional.h" #include "gtest/gtest.h" @@ -25,7 +26,6 @@ #include #include #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/time.h" @@ -47,17 +47,17 @@ const char overridden_fake_md_value[] = "overridden_fake_value"; void PrintAuthContext(bool is_client, const grpc_auth_context* ctx) { const grpc_auth_property* p; grpc_auth_property_iterator it; - gpr_log(GPR_INFO, "%s peer:", is_client ? "client" : "server"); - gpr_log(GPR_INFO, "\tauthenticated: %s", - grpc_auth_context_peer_is_authenticated(ctx) ? "YES" : "NO"); + LOG(INFO) << (is_client ? "client" : "server") << " peer:"; + LOG(INFO) << "\tauthenticated: " + << (grpc_auth_context_peer_is_authenticated(ctx) ? "YES" : "NO"); it = grpc_auth_context_peer_identity(ctx); while ((p = grpc_auth_property_iterator_next(&it)) != nullptr) { - gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); + LOG(INFO) << "\t\t" << p->name << ": " << p->value; } - gpr_log(GPR_INFO, "\tall properties:"); + LOG(INFO) << "\tall properties:"; it = grpc_auth_context_property_iterator(ctx); while ((p = grpc_auth_property_iterator_next(&it)) != nullptr) { - gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); + LOG(INFO) << "\t\t" << p->name << ": " << p->value; } } diff --git a/test/core/end2end/tests/disappearing_server.cc b/test/core/end2end/tests/disappearing_server.cc index 81cea5a5ad2..5b65e20eb57 100644 --- a/test/core/end2end/tests/disappearing_server.cc +++ b/test/core/end2end/tests/disappearing_server.cc @@ -18,10 +18,10 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/time.h" @@ -31,13 +31,13 @@ namespace grpc_core { static void OneRequestAndShutdownServer(CoreEnd2endTest& test) { - gpr_log(GPR_ERROR, "Create client side call"); + LOG(ERROR) << "Create client side call"; auto c = test.NewClientCall("/service/method") .Timeout(Duration::Seconds(30)) .Create(); CoreEnd2endTest::IncomingMetadata server_initial_md; CoreEnd2endTest::IncomingStatusOnClient server_status; - gpr_log(GPR_ERROR, "Start initial batch"); + LOG(ERROR) << "Start initial batch"; c.NewBatch(1) .SendInitialMetadata({}) .SendCloseFromClient() diff --git a/test/core/end2end/tests/filter_context.cc b/test/core/end2end/tests/filter_context.cc index b3e2759ef1f..7d53047f971 100644 --- a/test/core/end2end/tests/filter_context.cc +++ b/test/core/end2end/tests/filter_context.cc @@ -20,11 +20,11 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/status/status.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/channel/channel_fwd.h" #include "src/core/lib/channel/channel_stack.h" @@ -53,7 +53,7 @@ grpc_error_handle init_call_elem(grpc_call_element* elem, const grpc_call_element_args* args) { call_data* calld = static_cast(elem->call_data); calld->context = args->context; - gpr_log(GPR_INFO, "init_call_elem(): context=%p", args->context); + LOG(INFO) << "init_call_elem(): context=" << args->context; return absl::OkStatus(); } @@ -63,8 +63,8 @@ void start_transport_stream_op_batch(grpc_call_element* elem, // If batch payload context is not null (which will happen in some // cancellation cases), make sure we get the same context here that we // saw in init_call_elem(). - gpr_log(GPR_INFO, "start_transport_stream_op_batch(): context=%p", - batch->payload->context); + LOG(INFO) << "start_transport_stream_op_batch(): context=" + << batch->payload->context; if (batch->payload->context != nullptr) { CHECK(calld->context == batch->payload->context); } @@ -103,9 +103,6 @@ CORE_END2END_TEST(CoreEnd2endTest, FilterContext) { CoreConfiguration::RegisterBuilder([](CoreConfiguration::Builder* builder) { for (auto type : {GRPC_CLIENT_CHANNEL, GRPC_CLIENT_SUBCHANNEL, GRPC_CLIENT_DIRECT_CHANNEL, GRPC_SERVER_CHANNEL}) { - if (type == GRPC_SERVER_CHANNEL && IsPromiseBasedServerCallEnabled()) { - continue; - } builder->channel_init()->RegisterFilter(type, &test_filter); } }); diff --git a/test/core/end2end/tests/http2_stats.cc b/test/core/end2end/tests/http2_stats.cc index f0421d67dd0..a2931c98ea6 100644 --- a/test/core/end2end/tests/http2_stats.cc +++ b/test/core/end2end/tests/http2_stats.cc @@ -199,6 +199,7 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) { g_mu = new Mutex(); g_client_call_ended_notify = new CoreEnd2endTest::TestNotification(this); g_server_call_ended_notify = new CoreEnd2endTest::TestNotification(this); + GlobalStatsPluginRegistryTestPeer::ResetGlobalStatsPluginRegistry(); GlobalStatsPluginRegistry::RegisterStatsPlugin( std::make_shared()); auto send_from_client = RandomSlice(10); @@ -265,8 +266,6 @@ CORE_END2END_TEST(Http2FullstackSingleHopTest, StreamStats) { EXPECT_GE(server_transport_stats.incoming.framing_bytes, 32); EXPECT_LE(server_transport_stats.incoming.framing_bytes, 58); - delete ServerCallTracerFactory::Get(ChannelArgs()); - ServerCallTracerFactory::RegisterGlobal(nullptr); delete g_client_call_ended_notify; g_client_call_ended_notify = nullptr; delete g_server_call_ended_notify; diff --git a/test/core/end2end/tests/resource_quota_server.cc b/test/core/end2end/tests/resource_quota_server.cc index acf4c109089..0bc7a69e034 100644 --- a/test/core/end2end/tests/resource_quota_server.cc +++ b/test/core/end2end/tests/resource_quota_server.cc @@ -21,13 +21,13 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/str_format.h" #include "gtest/gtest.h" #include #include #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/experiments/experiments.h" @@ -146,11 +146,11 @@ CORE_END2END_TEST(ResourceQuotaTest, ResourceQuota) { cancelled_calls_on_server++; } } - gpr_log(GPR_INFO, - "Done. %d total calls: %d cancelled at server, %d cancelled at " - "client, %d timed out, %d unavailable.", - kNumCalls, cancelled_calls_on_server, cancelled_calls_on_client, - deadline_exceeded, unavailable); + LOG(INFO) << "Done. " << kNumCalls + << " total calls: " << cancelled_calls_on_server + << " cancelled at server, " << cancelled_calls_on_client + << " cancelled at client, " << deadline_exceeded << " timed out, " + << unavailable << " unavailable."; ShutdownServerAndNotify(0); Expect(0, PerformAction{[this](bool success) { diff --git a/test/core/end2end/tests/server_streaming.cc b/test/core/end2end/tests/server_streaming.cc index 76cd2ae7382..b6fd6f30511 100644 --- a/test/core/end2end/tests/server_streaming.cc +++ b/test/core/end2end/tests/server_streaming.cc @@ -19,10 +19,10 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/gprpp/time.h" #include "test/core/end2end/cq_verifier.h" @@ -70,7 +70,7 @@ void ServerStreaming(CoreEnd2endTest& test, int num_messages) { test.Expect(104, true); test.Step(); - gpr_log(GPR_DEBUG, "SEEN_STATUS:%d", seen_status); + VLOG(2) << "SEEN_STATUS:" << seen_status; // Client keeps reading messages till it gets the status int num_messages_received = 0; diff --git a/test/core/end2end/tests/simple_delayed_request.cc b/test/core/end2end/tests/simple_delayed_request.cc index e22ea978335..bbdfe4ab790 100644 --- a/test/core/end2end/tests/simple_delayed_request.cc +++ b/test/core/end2end/tests/simple_delayed_request.cc @@ -18,12 +18,12 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include #include #include -#include #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gprpp/time.h" @@ -37,17 +37,17 @@ CORE_END2END_TEST(Http2SingleHopTest, SimpleDelayedRequestShort) { .Set(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, 1000) .Set(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, 1000) .Set(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, 5000)); - gpr_log(GPR_ERROR, "Create client side call"); + LOG(ERROR) << "Create client side call"; auto c = NewClientCall("/foo").Timeout(Duration::Minutes(1)).Create(); IncomingMetadata server_initial_metadata; IncomingStatusOnClient server_status; - gpr_log(GPR_ERROR, "Start initial batch"); + LOG(ERROR) << "Start initial batch"; c.NewBatch(1) .SendInitialMetadata({}, GRPC_INITIAL_METADATA_WAIT_FOR_READY) .SendCloseFromClient() .RecvInitialMetadata(server_initial_metadata) .RecvStatusOnClient(server_status); - gpr_log(GPR_ERROR, "Start server"); + LOG(ERROR) << "Start server"; InitServer(ChannelArgs()); auto s = RequestCall(101); Expect(101, true); diff --git a/test/core/end2end/tests/simple_request.cc b/test/core/end2end/tests/simple_request.cc index 359489f6c2d..1e39734d327 100644 --- a/test/core/end2end/tests/simple_request.cc +++ b/test/core/end2end/tests/simple_request.cc @@ -22,13 +22,13 @@ #include #include +#include "absl/log/log.h" #include "absl/strings/match.h" #include "absl/types/optional.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include -#include #include "src/core/lib/debug/stats.h" #include "src/core/lib/debug/stats_data.h" @@ -91,7 +91,7 @@ void SimpleRequestBody(CoreEnd2endTest& test) { expected_calls *= 2; } auto after = global_stats().Collect(); - gpr_log(GPR_DEBUG, "%s", StatsAsJson(after.get()).c_str()); + VLOG(2) << StatsAsJson(after.get()); EXPECT_EQ(after->client_calls_created - before->client_calls_created, expected_calls); EXPECT_EQ(after->server_calls_created - before->server_calls_created, diff --git a/test/core/end2end/tests/timeout_before_request_call.cc b/test/core/end2end/tests/timeout_before_request_call.cc index 5ad6a9872a1..bb61acd648e 100644 --- a/test/core/end2end/tests/timeout_before_request_call.cc +++ b/test/core/end2end/tests/timeout_before_request_call.cc @@ -16,6 +16,7 @@ #include +#include "absl/log/log.h" #include "gtest/gtest.h" #include @@ -147,7 +148,7 @@ CORE_END2END_TEST(CoreDeadlineSingleHopTest, bool got_call = false; std::unique_ptr client_close; Expect(2, MaybePerformAction{[this, &s, &got_call, &client_close](bool ok) { - gpr_log(GPR_INFO, "\n***\n*** got call: %d\n***", ok); + LOG(INFO) << "\n***\n*** got call: " << ok << "\n***"; got_call = true; if (ok) { // If we successfully get a call, then we should additionally get a diff --git a/test/core/event_engine/event_engine_test_utils.cc b/test/core/event_engine/event_engine_test_utils.cc index cc036ad5d3b..32ab6ac5276 100644 --- a/test/core/event_engine/event_engine_test_utils.cc +++ b/test/core/event_engine/event_engine_test_utils.cc @@ -41,6 +41,7 @@ #include "src/core/lib/gprpp/notification.h" #include "src/core/lib/gprpp/time.h" #include "src/core/lib/resource_quota/memory_quota.h" +#include "test/core/test_util/build.h" // IWYU pragma: no_include @@ -77,7 +78,10 @@ std::string GetNextSendMessage() { } void WaitForSingleOwner(std::shared_ptr engine) { + int n = 0; while (engine.use_count() > 1) { + ++n; + if (n % 100 == 0) AsanAssertNoLeaks(); GRPC_LOG_EVERY_N_SEC(2, GPR_INFO, "engine.use_count() = %ld", engine.use_count()); absl::SleepFor(absl::Milliseconds(100)); diff --git a/test/core/event_engine/event_engine_test_utils.h b/test/core/event_engine/event_engine_test_utils.h index 67bbe42d35d..debef7a0449 100644 --- a/test/core/event_engine/event_engine_test_utils.h +++ b/test/core/event_engine/event_engine_test_utils.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -159,6 +160,70 @@ class NotifyOnDelete { grpc_core::Notification* signal_; }; +// An endpoint implementation that supports Read and Write via std::threads. +// Passing a grpc_core::Notification will allow owners to know when all +// in-flight callbacks have been run, and all endpoint state has been destroyed. +class ThreadedNoopEndpoint : public EventEngine::Endpoint { + public: + explicit ThreadedNoopEndpoint(grpc_core::Notification* destroyed) + : state_(std::make_shared(destroyed)) {} + ~ThreadedNoopEndpoint() override { + std::thread deleter([state = state_]() { + CleanupThread(state->read); + CleanupThread(state->write); + }); + deleter.detach(); + } + + bool Read(absl::AnyInvocable on_read, SliceBuffer* buffer, + const ReadArgs* /* args */) override { + buffer->Clear(); + CleanupThread(state_->read); + state_->read = new std::thread([cb = std::move(on_read)]() mutable { + cb(absl::UnknownError("test")); + }); + return false; + } + + bool Write(absl::AnyInvocable on_writable, + SliceBuffer* data, const WriteArgs* /* args */) override { + data->Clear(); + CleanupThread(state_->write); + state_->write = new std::thread([cb = std::move(on_writable)]() mutable { + cb(absl::UnknownError("test")); + }); + return false; + } + + const EventEngine::ResolvedAddress& GetPeerAddress() const override { + return peer_; + } + + const EventEngine::ResolvedAddress& GetLocalAddress() const override { + return local_; + } + + private: + struct EndpointState { + explicit EndpointState(grpc_core::Notification* deleter) + : delete_notifier_(deleter) {} + std::thread* read = nullptr; + std::thread* write = nullptr; + NotifyOnDelete delete_notifier_; + }; + + static void CleanupThread(std::thread* thd) { + if (thd != nullptr) { + thd->join(); + delete thd; + } + } + + std::shared_ptr state_; + EventEngine::ResolvedAddress peer_; + EventEngine::ResolvedAddress local_; +}; + } // namespace experimental } // namespace grpc_event_engine diff --git a/test/core/gprpp/BUILD b/test/core/gprpp/BUILD index b6ca769f46d..177c5809b0c 100644 --- a/test/core/gprpp/BUILD +++ b/test/core/gprpp/BUILD @@ -60,6 +60,20 @@ grpc_cc_test( ], ) +grpc_cc_test( + name = "dump_args_test", + srcs = ["dump_args_test.cc"], + external_deps = [ + "gtest", + ], + language = "C++", + uses_event_engine = False, + uses_polling = False, + deps = [ + "//src/core:dump_args", + ], +) + # TODO(hork): solidify fork support requirements for EventEngines grpc_cc_test( name = "fork_test", diff --git a/test/core/gprpp/dump_args_test.cc b/test/core/gprpp/dump_args_test.cc new file mode 100644 index 00000000000..2207d4eab62 --- /dev/null +++ b/test/core/gprpp/dump_args_test.cc @@ -0,0 +1,44 @@ +// Copyright 2024 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 "src/core/lib/gprpp/dump_args.h" + +#include + +#include "gtest/gtest.h" + +template +std::string Stringify(const T& t) { + std::ostringstream oss; + oss << t; + return oss.str(); +} + +int add(int a, int b) { return a + b; } + +TEST(DumpArgsTest, Basic) { + int a = 1; + int b = 2; + int c = 3; + EXPECT_EQ("a = 1, b = 2, c = 3", Stringify(GRPC_DUMP_ARGS(a, b, c))); +} + +TEST(DumpArgsTest, FunctionCall) { + EXPECT_EQ("add(1, 2) = 3", Stringify(GRPC_DUMP_ARGS(add(1, 2)))); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/core/load_balancing/pick_first_test.cc b/test/core/load_balancing/pick_first_test.cc index e3dfd04ffc9..839afa62a3c 100644 --- a/test/core/load_balancing/pick_first_test.cc +++ b/test/core/load_balancing/pick_first_test.cc @@ -1307,8 +1307,8 @@ TEST_F(PickFirstTest, MetricValues) { // The first subchannel's connection attempt fails. subchannel->SetConnectivityState(GRPC_CHANNEL_TRANSIENT_FAILURE, absl::UnavailableError("failed to connect")); - EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsFailed, - kLabelValues, {}), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsFailed, + kLabelValues, {}), ::testing::Optional(1)); // The LB policy will start a connection attempt on the second subchannel. EXPECT_TRUE(subchannel2->ConnectionRequested()); @@ -1317,8 +1317,8 @@ TEST_F(PickFirstTest, MetricValues) { subchannel2->SetConnectivityState(GRPC_CHANNEL_CONNECTING); // The connection attempt succeeds. subchannel2->SetConnectivityState(GRPC_CHANNEL_READY); - EXPECT_THAT(stats_plugin->GetCounterValue(kConnectionAttemptsSucceeded, - kLabelValues, {}), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kConnectionAttemptsSucceeded, + kLabelValues, {}), ::testing::Optional(1)); // The LB policy will report CONNECTING some number of times (doesn't // matter how many) and then report READY. @@ -1332,8 +1332,9 @@ TEST_F(PickFirstTest, MetricValues) { subchannel2->SetConnectivityState(GRPC_CHANNEL_IDLE); ExpectReresolutionRequest(); ExpectState(GRPC_CHANNEL_IDLE); - EXPECT_THAT(stats_plugin->GetCounterValue(kDisconnections, kLabelValues, {}), - ::testing::Optional(1)); + EXPECT_THAT( + stats_plugin->GetUInt64CounterValue(kDisconnections, kLabelValues, {}), + ::testing::Optional(1)); } class PickFirstHealthCheckingEnabledTest : public PickFirstTest { diff --git a/test/core/load_balancing/weighted_round_robin_test.cc b/test/core/load_balancing/weighted_round_robin_test.cc index 9177562e919..9a5eebba751 100644 --- a/test/core/load_balancing/weighted_round_robin_test.cc +++ b/test/core/load_balancing/weighted_round_robin_test.cc @@ -1113,8 +1113,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) { /*qps=*/100.0, /*eps=*/0.0)}}, {{kAddresses[0], 1}, {kAddresses[1], 3}, {kAddresses[2], 3}}); // Check endpoint weights. - EXPECT_THAT(stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetDoubleHistogramValue( + kEndpointWeights, kLabelValues, kOptionalLabelValues), ::testing::Optional(::testing::ElementsAre( // Picker created for first endpoint becoming READY. 0, @@ -1135,17 +1135,18 @@ TEST_F(WeightedRoundRobinTest, MetricValues) { ::testing::DoubleNear(333.333344, 0.000001)))); // RR fallback should trigger for the first 5 updates above, because // there are less than two endpoints with valid weights. - EXPECT_THAT(stats_plugin->GetCounterValue(kRrFallback, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue(kRrFallback, kLabelValues, + kOptionalLabelValues), ::testing::Optional(5)); // Endpoint-not-yet-usable will be incremented once for every endpoint // with weight 0 above. - EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightNotYetUsable, - kLabelValues, kOptionalLabelValues), - ::testing::Optional(10)); + EXPECT_THAT( + stats_plugin->GetUInt64CounterValue(kEndpointWeightNotYetUsable, + kLabelValues, kOptionalLabelValues), + ::testing::Optional(10)); // There are no stale endpoint weights so far. - EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue( + kEndpointWeightStale, kLabelValues, kOptionalLabelValues), ::testing::Optional(0)); // Advance time to make weights stale and trigger the timer callback // to recompute weights. @@ -1156,8 +1157,8 @@ TEST_F(WeightedRoundRobinTest, MetricValues) { picker.get(), {}, {{kAddresses[0], 3}, {kAddresses[1], 3}, {kAddresses[2], 3}}); // All three endpoints should now have stale weights. - EXPECT_THAT(stats_plugin->GetCounterValue(kEndpointWeightStale, kLabelValues, - kOptionalLabelValues), + EXPECT_THAT(stats_plugin->GetUInt64CounterValue( + kEndpointWeightStale, kLabelValues, kOptionalLabelValues), ::testing::Optional(3)); } diff --git a/test/core/surface/channel_init_test.cc b/test/core/surface/channel_init_test.cc index 1b0baeafba0..a90777973c3 100644 --- a/test/core/surface/channel_init_test.cc +++ b/test/core/surface/channel_init_test.cc @@ -23,7 +23,10 @@ #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/channel_stack_builder_impl.h" +#include "src/core/lib/channel/promise_based_filter.h" +#include "src/core/lib/resource_quota/resource_quota.h" #include "src/core/lib/surface/channel_stack_type.h" +#include "src/core/lib/transport/call_arena_allocator.h" #include "test/core/test_util/test_config.h" namespace grpc_core { @@ -208,7 +211,7 @@ class TestFilter1 { explicit TestFilter1(int* p) : p_(p) {} static absl::StatusOr> Create( - const ChannelArgs& args, Empty) { + const ChannelArgs& args, ChannelFilter::Args) { EXPECT_EQ(args.GetInt("foo"), 1); return std::make_unique(args.GetPointer("p")); } @@ -250,19 +253,23 @@ TEST(ChannelInitTest, CanCreateFilterWithCall) { b.RegisterFilter(GRPC_CLIENT_CHANNEL); auto init = b.Build(); int p = 0; - auto segment = init.CreateStackSegment( - GRPC_CLIENT_CHANNEL, - ChannelArgs().Set("foo", 1).Set("p", ChannelArgs::UnownedPointer(&p))); - ASSERT_TRUE(segment.ok()) << segment.status(); - CallFilters::StackBuilder stack_builder; - segment->AddToCallFilterStack(stack_builder); - segment = absl::CancelledError(); // force the segment to be destroyed - auto stack = stack_builder.Build(); - { - CallFilters call_filters(Arena::MakePooled()); - call_filters.SetStack(std::move(stack)); - } + InterceptionChainBuilder chain_builder{ + ChannelArgs().Set("foo", 1).Set("p", ChannelArgs::UnownedPointer(&p))}; + init.AddToInterceptionChainBuilder(GRPC_CLIENT_CHANNEL, chain_builder); + int handled = 0; + auto stack = chain_builder.Build(MakeCallDestinationFromHandlerFunction( + [&handled](CallHandler) { ++handled; })); + ASSERT_TRUE(stack.ok()) << stack.status(); + RefCountedPtr allocator = + MakeRefCounted( + ResourceQuota::Default()->memory_quota()->CreateMemoryAllocator( + "test"), + 1024); + auto call = MakeCallPair(Arena::MakePooled(), nullptr, + allocator->MakeArena(), allocator, nullptr); + (*stack)->StartCall(std::move(call.handler)); EXPECT_EQ(p, 1); + EXPECT_EQ(handled, 1); } } // namespace diff --git a/test/core/test_util/build.cc b/test/core/test_util/build.cc index 04d39e9574d..36510696681 100644 --- a/test/core/test_util/build.cc +++ b/test/core/test_util/build.cc @@ -12,62 +12,78 @@ // See the License for the specific language governing permissions and // limitations under the License. -bool BuiltUnderValgrind() { -#ifdef RUNNING_ON_VALGRIND - return true; -#else - return false; -#endif -} - -bool BuiltUnderTsan() { +// Define GRPC_BUILD_HAS_ASAN as 1 or 0 depending on if we're building under +// ASAN. #if defined(__has_feature) -#if __has_feature(thread_sanitizer) - return true; +#if __has_feature(address_sanitizer) +#define GRPC_BUILD_HAS_ASAN 1 #else - return false; +#define GRPC_BUILD_HAS_ASAN 0 #endif #else -#ifdef THREAD_SANITIZER - return true; +#ifdef ADDRESS_SANITIZER +#define GRPC_BUILD_HAS_ASAN 1 #else - return false; +#define GRPC_BUILD_HAS_ASAN 0 #endif #endif -} -bool BuiltUnderAsan() { +// Define GRPC_BUILD_HAS_TSAN as 1 or 0 depending on if we're building under +// TSAN. #if defined(__has_feature) -#if __has_feature(address_sanitizer) - return true; +#if __has_feature(thread_sanitizer) +#define GRPC_BUILD_HAS_TSAN 1 #else - return false; +#define GRPC_BUILD_HAS_TSAN 0 #endif #else -#ifdef ADDRESS_SANITIZER - return true; +#ifdef THREAD_SANITIZER +#define GRPC_BUILD_HAS_TSAN 1 #else - return false; +#define GRPC_BUILD_HAS_TSAN 0 #endif #endif -} -bool BuiltUnderMsan() { +// Define GRPC_BUILD_HAS_MSAN as 1 or 0 depending on if we're building under +// MSAN. #if defined(__has_feature) #if __has_feature(memory_sanitizer) - return true; +#define GRPC_BUILD_HAS_MSAN 1 #else - return false; +#define GRPC_BUILD_HAS_MSAN 0 #endif #else #ifdef MEMORY_SANITIZER +#define GRPC_BUILD_HAS_MSAN 1 +#else +#define GRPC_BUILD_HAS_MSAN 0 +#endif +#endif + +#if GRPC_BUILD_HAS_ASAN +#include +#endif + +bool BuiltUnderValgrind() { +#ifdef RUNNING_ON_VALGRIND return true; #else return false; #endif +} + +bool BuiltUnderTsan() { return GRPC_BUILD_HAS_TSAN != 0; } + +bool BuiltUnderAsan() { return GRPC_BUILD_HAS_ASAN != 0; } + +void AsanAssertNoLeaks() { +#if GRPC_BUILD_HAS_ASAN + __lsan_do_leak_check(); #endif } +bool BuiltUnderMsan() { return GRPC_BUILD_HAS_MSAN != 0; } + bool BuiltUnderUbsan() { #ifdef GRPC_UBSAN return true; diff --git a/test/core/test_util/build.h b/test/core/test_util/build.h index 20bc21954ff..8574dfe8d3c 100644 --- a/test/core/test_util/build.h +++ b/test/core/test_util/build.h @@ -30,4 +30,7 @@ bool BuiltUnderMsan(); // Returns whether this is built under UndefinedBehaviorSanitizer bool BuiltUnderUbsan(); +// Force a leak check if built under ASAN. If there are leaks, crash. +void AsanAssertNoLeaks(); + #endif // GRPC_TEST_CORE_TEST_UTIL_BUILD_H diff --git a/test/core/test_util/fake_stats_plugin.cc b/test/core/test_util/fake_stats_plugin.cc index 50b86a278cc..abc0a6a82ff 100644 --- a/test/core/test_util/fake_stats_plugin.cc +++ b/test/core/test_util/fake_stats_plugin.cc @@ -125,8 +125,8 @@ void GlobalInstrumentsRegistryTestPeer::ResetGlobalInstrumentsRegistry() { namespace { -template -absl::optional FindInstrument( +absl::optional +FindInstrument( const std::vector& instruments, absl::string_view name, GlobalInstrumentsRegistry::ValueType value_type, @@ -134,7 +134,7 @@ absl::optional FindInstrument( for (const auto& descriptor : instruments) { if (descriptor.name == name && descriptor.value_type == value_type && descriptor.instrument_type == instrument_type) { - HandleType handle; + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle; handle.index = descriptor.index; return handle; } @@ -144,57 +144,51 @@ absl::optional FindInstrument( } // namespace -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindUInt64CounterHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kUInt64, - GlobalInstrumentsRegistry::InstrumentType::kCounter); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kCounter); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindDoubleCounterHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kDouble, - GlobalInstrumentsRegistry::InstrumentType::kCounter); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kCounter); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindUInt64HistogramHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kUInt64, - GlobalInstrumentsRegistry::InstrumentType::kHistogram); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kUInt64, + GlobalInstrumentsRegistry::InstrumentType::kHistogram); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindDoubleHistogramHandleByName( absl::string_view name) { - return FindInstrument( - GlobalInstrumentsRegistry::GetInstrumentList(), name, - GlobalInstrumentsRegistry::ValueType::kDouble, - GlobalInstrumentsRegistry::InstrumentType::kHistogram); + return FindInstrument(GlobalInstrumentsRegistry::GetInstrumentList(), name, + GlobalInstrumentsRegistry::ValueType::kDouble, + GlobalInstrumentsRegistry::InstrumentType::kHistogram); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindCallbackInt64GaugeHandleByName( absl::string_view name) { - return FindInstrument< - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle>( + return FindInstrument( GlobalInstrumentsRegistry::GetInstrumentList(), name, GlobalInstrumentsRegistry::ValueType::kInt64, GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); } -absl::optional +absl::optional GlobalInstrumentsRegistryTestPeer::FindCallbackDoubleGaugeHandleByName( absl::string_view name) { - return FindInstrument< - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle>( + return FindInstrument( GlobalInstrumentsRegistry::GetInstrumentList(), name, GlobalInstrumentsRegistry::ValueType::kDouble, GlobalInstrumentsRegistry::InstrumentType::kCallbackGauge); diff --git a/test/core/test_util/fake_stats_plugin.h b/test/core/test_util/fake_stats_plugin.h index 29a793dc5c3..655dfe0002c 100644 --- a/test/core/test_util/fake_stats_plugin.h +++ b/test/core/test_util/fake_stats_plugin.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "absl/container/flat_hash_map.h" @@ -270,8 +271,8 @@ class FakeStatsPlugin : public StatsPlugin { } void AddCounter( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_values) override { // The problem with this approach is that we initialize uint64_counters_ in // BuildAndRegister by querying the GlobalInstrumentsRegistry at the time. @@ -283,7 +284,8 @@ class FakeStatsPlugin : public StatsPlugin { // GlobalInstrumentsRegistry everytime a metric is recorded. But this is not // a concern for now. gpr_log(GPR_INFO, - "FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%lu, " + "FakeStatsPlugin[%p]::AddCounter(index=%u, value=(uint64)%" PRIu64 + ", " "label_values={%s}, optional_label_values={%s}", this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(), @@ -294,7 +296,7 @@ class FakeStatsPlugin : public StatsPlugin { iter->second.Add(value, label_values, optional_values); } void AddCounter( - GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, double value, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, @@ -309,23 +311,24 @@ class FakeStatsPlugin : public StatsPlugin { iter->second.Add(value, label_values, optional_values); } void RecordHistogram( - GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, - uint64_t value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, uint64_t value, + absl::Span label_values, absl::Span optional_values) override { - gpr_log(GPR_INFO, - "FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%lu, " - "label_values={%s}, optional_label_values={%s}", - this, handle.index, value, - absl::StrJoin(label_values, ", ").c_str(), - absl::StrJoin(optional_values, ", ").c_str()); + gpr_log( + GPR_INFO, + "FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(uint64)%" PRIu64 + ", " + "label_values={%s}, optional_label_values={%s}", + this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(), + absl::StrJoin(optional_values, ", ").c_str()); MutexLock lock(&mu_); auto iter = uint64_histograms_.find(handle.index); if (iter == uint64_histograms_.end()) return; iter->second.Record(value, label_values, optional_values); } void RecordHistogram( - GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, - double value, absl::Span label_values, + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::RecordHistogram(index=%u, value=(double)%f, " @@ -358,8 +361,8 @@ class FakeStatsPlugin : public StatsPlugin { return nullptr; } - absl::optional GetCounterValue( - GlobalInstrumentsRegistry::GlobalUInt64CounterHandle handle, + absl::optional GetUInt64CounterValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -369,8 +372,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValue(label_values, optional_values); } - absl::optional GetCounterValue( - GlobalInstrumentsRegistry::GlobalDoubleCounterHandle handle, + absl::optional GetDoubleCounterValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -380,8 +383,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValue(label_values, optional_values); } - absl::optional> GetHistogramValue( - GlobalInstrumentsRegistry::GlobalUInt64HistogramHandle handle, + absl::optional> GetUInt64HistogramValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -391,8 +394,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValues(label_values, optional_values); } - absl::optional> GetHistogramValue( - GlobalInstrumentsRegistry::GlobalDoubleHistogramHandle handle, + absl::optional> GetDoubleHistogramValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&mu_); @@ -410,8 +413,8 @@ class FakeStatsPlugin : public StatsPlugin { } gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::TriggerCallbacks(): END", this); } - absl::optional GetCallbackGaugeValue( - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, + absl::optional GetInt64CallbackGaugeValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&callback_mu_); @@ -421,8 +424,8 @@ class FakeStatsPlugin : public StatsPlugin { } return iter->second.GetValue(label_values, optional_values); } - absl::optional GetCallbackGaugeValue( - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle, + absl::optional GetDoubleCallbackGaugeValue( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, absl::Span label_values, absl::Span optional_values) { MutexLock lock(&callback_mu_); @@ -438,13 +441,14 @@ class FakeStatsPlugin : public StatsPlugin { public: explicit Reporter(FakeStatsPlugin& plugin) : plugin_(plugin) {} - void Report( - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle handle, - int64_t value, absl::Span label_values, + void ReportInt64( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, int64_t value, + absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::Reporter::Report(index=%u, " - "value=(uint64)%ld, label_values={%s}, " + "value=(int64_t)%" PRId64 + ", label_values={%s}, " "optional_label_values={%s}", this, handle.index, value, absl::StrJoin(label_values, ", ").c_str(), @@ -455,9 +459,9 @@ class FakeStatsPlugin : public StatsPlugin { iter->second.Set(value, label_values, optional_values); } - void Report( - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle handle, - double value, absl::Span label_values, + void ReportDouble( + GlobalInstrumentsRegistry::GlobalInstrumentHandle handle, double value, + absl::Span label_values, absl::Span optional_values) override { gpr_log(GPR_INFO, "FakeStatsPlugin[%p]::Reporter::Report(index=%u, " @@ -654,19 +658,17 @@ class GlobalInstrumentsRegistryTestPeer { public: static void ResetGlobalInstrumentsRegistry(); - static absl::optional + static absl::optional FindUInt64CounterHandleByName(absl::string_view name); - static absl::optional + static absl::optional FindDoubleCounterHandleByName(absl::string_view name); - static absl::optional + static absl::optional FindUInt64HistogramHandleByName(absl::string_view name); - static absl::optional + static absl::optional FindDoubleHistogramHandleByName(absl::string_view name); - static absl::optional< - GlobalInstrumentsRegistry::GlobalCallbackInt64GaugeHandle> + static absl::optional FindCallbackInt64GaugeHandleByName(absl::string_view name); - static absl::optional< - GlobalInstrumentsRegistry::GlobalCallbackDoubleGaugeHandle> + static absl::optional FindCallbackDoubleGaugeHandleByName(absl::string_view name); static GlobalInstrumentsRegistry::GlobalInstrumentDescriptor* diff --git a/test/core/transport/chaotic_good/chaotic_good_server_test.cc b/test/core/transport/chaotic_good/chaotic_good_server_test.cc index b5b058b43ee..40de0b35cbe 100644 --- a/test/core/transport/chaotic_good/chaotic_good_server_test.cc +++ b/test/core/transport/chaotic_good/chaotic_good_server_test.cc @@ -39,6 +39,7 @@ #include "src/core/lib/uri/uri_parser.h" #include "src/core/server/server.h" #include "test/core/event_engine/event_engine_test_utils.h" +#include "test/core/test_util/build.h" #include "test/core/test_util/port.h" #include "test/core/test_util/test_config.h" @@ -67,7 +68,10 @@ class ChaoticGoodServerTest : public ::testing::Test { auto ev = grpc_completion_queue_pluck( shutdown_cq, nullptr, grpc_timeout_milliseconds_to_deadline(15000), nullptr); - CHECK(ev.type == GRPC_OP_COMPLETE); + if (ev.type == GRPC_QUEUE_TIMEOUT) { + AsanAssertNoLeaks(); + } + CHECK_EQ(ev.type, GRPC_OP_COMPLETE); CHECK_EQ(ev.tag, nullptr); grpc_completion_queue_destroy(shutdown_cq); grpc_server_destroy(server_); diff --git a/test/core/transport/chaotic_good/server_transport_test.cc b/test/core/transport/chaotic_good/server_transport_test.cc index a5dd0008b9a..da80f94781f 100644 --- a/test/core/transport/chaotic_good/server_transport_test.cc +++ b/test/core/transport/chaotic_good/server_transport_test.cc @@ -82,19 +82,19 @@ ServerMetadataHandle TestTrailingMetadata() { return md; } -class MockAcceptor : public ServerTransport::Acceptor { +class MockCallDestination : public UnstartedCallDestination { public: - virtual ~MockAcceptor() = default; - MOCK_METHOD(Arena*, CreateArena, (), (override)); - MOCK_METHOD(absl::StatusOr, CreateCall, - (ClientMetadataHandle client_initial_metadata, Arena* arena), + ~MockCallDestination() override = default; + MOCK_METHOD(void, Orphaned, (), (override)); + MOCK_METHOD(void, StartCall, (UnstartedCallHandler unstarted_call_handler), (override)); }; TEST_F(TransportTest, ReadAndWriteOneMessage) { MockPromiseEndpoint control_endpoint; MockPromiseEndpoint data_endpoint; - StrictMock acceptor; + auto call_destination = MakeRefCounted>(); + EXPECT_CALL(*call_destination, Orphaned()).Times(1); auto transport = MakeOrphanable( CoreConfiguration::Get() .channel_args_preconditioning() @@ -112,19 +112,21 @@ TEST_F(TransportTest, ReadAndWriteOneMessage) { data_endpoint.ExpectRead( {EventEngineSlice::FromCopiedString("12345678"), Zeros(56)}, nullptr); // Once that's read we'll create a new call - auto* call_arena = MakeArena(); - EXPECT_CALL(acceptor, CreateArena).WillOnce(Return(call_arena)); StrictMock> on_done; - EXPECT_CALL(acceptor, CreateCall(_, call_arena)) - .WillOnce(WithArgs<0>([this, call_arena, &on_done]( - ClientMetadataHandle client_initial_metadata) { - EXPECT_EQ(client_initial_metadata->get_pointer(HttpPathMetadata()) + auto control_address = + grpc_event_engine::experimental::URIToResolvedAddress("ipv4:1.2.3.4:5678") + .value(); + EXPECT_CALL(*control_endpoint.endpoint, GetPeerAddress) + .WillRepeatedly([&control_address]() { return control_address; }); + EXPECT_CALL(*call_destination, StartCall(_)) + .WillOnce(WithArgs<0>([&on_done]( + UnstartedCallHandler unstarted_call_handler) { + EXPECT_EQ(unstarted_call_handler.UnprocessedClientInitialMetadata() + .get_pointer(HttpPathMetadata()) ->as_string_view(), "/demo.Service/Step"); - CallInitiatorAndHandler call = MakeCallPair( - std::move(client_initial_metadata), event_engine().get(), - call_arena, call_arena_allocator(), nullptr); - auto handler = call.handler.V2HackToStartCallWithoutACallFilterStack(); + auto handler = + unstarted_call_handler.V2HackToStartCallWithoutACallFilterStack(); handler.SpawnInfallible("test-io", [&on_done, handler]() mutable { return Seq( handler.PullClientInitialMetadata(), @@ -163,9 +165,8 @@ TEST_F(TransportTest, ReadAndWriteOneMessage) { return Empty{}; }); }); - return std::move(call.initiator); })); - transport->SetAcceptor(&acceptor); + transport->SetCallDestination(call_destination); EXPECT_CALL(on_done, Call()); EXPECT_CALL(*control_endpoint.endpoint, Read) .InSequence(control_endpoint.read_sequence) diff --git a/test/core/transport/test_suite/call_content.cc b/test/core/transport/test_suite/call_content.cc index 9e334f24fb6..cfcac0bf91b 100644 --- a/test/core/transport/test_suite/call_content.cc +++ b/test/core/transport/test_suite/call_content.cc @@ -62,7 +62,7 @@ void FillMetadata(const std::vector>& md, } // namespace TRANSPORT_TEST(UnaryWithSomeContent) { - SetServerAcceptor(); + SetServerCallDestination(); const auto client_initial_metadata = RandomMetadata(); const auto server_initial_metadata = RandomMetadata(); const auto server_trailing_metadata = RandomMetadata(); diff --git a/test/core/transport/test_suite/call_shapes.cc b/test/core/transport/test_suite/call_shapes.cc index fdae653119d..89ee26ccd2f 100644 --- a/test/core/transport/test_suite/call_shapes.cc +++ b/test/core/transport/test_suite/call_shapes.cc @@ -17,7 +17,7 @@ namespace grpc_core { TRANSPORT_TEST(MetadataOnlyRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -72,7 +72,7 @@ TRANSPORT_TEST(MetadataOnlyRequestServerAbortsAfterInitialMetadata) { "wrong status code: we don't care for any cases we're " "rolling out soon, so leaving this disabled."; - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -125,7 +125,7 @@ TRANSPORT_TEST(MetadataOnlyRequestServerAbortsImmediately) { "wrong status code: we don't care for any cases we're " "rolling out soon, so leaving this disabled."; - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -165,7 +165,7 @@ TRANSPORT_TEST(MetadataOnlyRequestServerAbortsImmediately) { } TRANSPORT_TEST(CanCreateCallThenAbandonIt) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -178,7 +178,7 @@ TRANSPORT_TEST(CanCreateCallThenAbandonIt) { } TRANSPORT_TEST(UnaryRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -257,7 +257,7 @@ TRANSPORT_TEST(UnaryRequest) { } TRANSPORT_TEST(UnaryRequestOmitCheckEndOfStream) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -326,7 +326,7 @@ TRANSPORT_TEST(UnaryRequestOmitCheckEndOfStream) { } TRANSPORT_TEST(UnaryRequestWaitForServerInitialMetadataBeforeSendingPayload) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -404,7 +404,7 @@ TRANSPORT_TEST(UnaryRequestWaitForServerInitialMetadataBeforeSendingPayload) { } TRANSPORT_TEST(ClientStreamingRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); @@ -518,7 +518,7 @@ TRANSPORT_TEST(ClientStreamingRequest) { } TRANSPORT_TEST(ServerStreamingRequest) { - SetServerAcceptor(); + SetServerCallDestination(); auto md = Arena::MakePooled(); md->Set(HttpPathMetadata(), Slice::FromExternalString("/foo/bar")); auto initiator = CreateCall(std::move(md)); diff --git a/test/core/transport/test_suite/inproc_fixture.cc b/test/core/transport/test_suite/inproc_fixture.cc index 357bbef66be..65468229341 100644 --- a/test/core/transport/test_suite/inproc_fixture.cc +++ b/test/core/transport/test_suite/inproc_fixture.cc @@ -13,12 +13,16 @@ // limitations under the License. #include "src/core/ext/transport/inproc/inproc_transport.h" +#include "src/core/lib/config/core_configuration.h" #include "test/core/transport/test_suite/fixture.h" namespace grpc_core { TRANSPORT_FIXTURE(Inproc) { - auto transports = MakeInProcessTransportPair(); + auto transports = + MakeInProcessTransportPair(CoreConfiguration::Get() + .channel_args_preconditioning() + .PreconditionChannelArgs(nullptr)); return {std::move(transports.first), std::move(transports.second)}; } diff --git a/test/core/transport/test_suite/no_op.cc b/test/core/transport/test_suite/no_op.cc index 0efd226257d..26e21e44e32 100644 --- a/test/core/transport/test_suite/no_op.cc +++ b/test/core/transport/test_suite/no_op.cc @@ -20,8 +20,8 @@ TRANSPORT_TEST(NoOp) {} TRANSPORT_TEST(WaitForAllPendingWork) { WaitForAllPendingWork(); } -TRANSPORT_TEST(SetServerAcceptorAndFinish) { - SetServerAcceptor(); +TRANSPORT_TEST(SetServerCallDestinationAndFinish) { + SetServerCallDestination(); WaitForAllPendingWork(); } diff --git a/test/core/transport/test_suite/stress.cc b/test/core/transport/test_suite/stress.cc index ca20fb7ff3f..e791bb18b8f 100644 --- a/test/core/transport/test_suite/stress.cc +++ b/test/core/transport/test_suite/stress.cc @@ -19,7 +19,7 @@ namespace grpc_core { TRANSPORT_TEST(ManyUnaryRequests) { - SetServerAcceptor(); + SetServerCallDestination(); const int kNumRequests = absl::LogUniform(rng(), 10, 100); std::list call_names; auto make_call_name = [&call_names](int i, diff --git a/test/core/transport/test_suite/test.cc b/test/core/transport/test_suite/test.cc index e170c9acda6..c228196983e 100644 --- a/test/core/transport/test_suite/test.cc +++ b/test/core/transport/test_suite/test.cc @@ -52,8 +52,9 @@ void TransportTest::RunTest() { event_engine_->UnsetGlobalHooks(); } -void TransportTest::SetServerAcceptor() { - transport_pair_.server->server_transport()->SetAcceptor(&acceptor_); +void TransportTest::SetServerCallDestination() { + transport_pair_.server->server_transport()->SetCallDestination( + server_call_destination_); } CallInitiator TransportTest::CreateCall( @@ -71,8 +72,10 @@ CallInitiator TransportTest::CreateCall( CallHandler TransportTest::TickUntilServerCall() { WatchDog watchdog(this); for (;;) { - auto handler = acceptor_.PopHandler(); - if (handler.has_value()) return std::move(*handler); + auto handler = server_call_destination_->PopHandler(); + if (handler.has_value()) { + return std::move(*handler); + } event_engine_->Tick(); } } @@ -227,22 +230,14 @@ std::string TransportTest::RandomMessage() { } /////////////////////////////////////////////////////////////////////////////// -// TransportTest::Acceptor - -Arena* TransportTest::Acceptor::CreateArena() { - return test_->call_arena_allocator_->MakeArena(); -} +// TransportTest::ServerCallDestination -absl::StatusOr TransportTest::Acceptor::CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) { - auto call = MakeCallPair(std::move(client_initial_metadata), - test_->event_engine_.get(), arena, - test_->call_arena_allocator_, nullptr); - handlers_.push(call.handler.V2HackToStartCallWithoutACallFilterStack()); - return std::move(call.initiator); +void TransportTest::ServerCallDestination::StartCall( + UnstartedCallHandler handler) { + handlers_.push(handler.V2HackToStartCallWithoutACallFilterStack()); } -absl::optional TransportTest::Acceptor::PopHandler() { +absl::optional TransportTest::ServerCallDestination::PopHandler() { if (!handlers_.empty()) { auto handler = std::move(handlers_.front()); handlers_.pop(); diff --git a/test/core/transport/test_suite/test.h b/test/core/transport/test_suite/test.h index 1add21cdd29..841b8cedfc8 100644 --- a/test/core/transport/test_suite/test.h +++ b/test/core/transport/test_suite/test.h @@ -32,6 +32,7 @@ #include "src/core/lib/resource_quota/resource_quota.h" #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.h" #include "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.pb.h" +#include "test/core/test_util/test_config.h" #include "test/core/transport/test_suite/fixture.h" namespace grpc_core { @@ -220,7 +221,7 @@ class TransportTest : public ::testing::Test { fixture_(std::move(fixture)), rng_(rng) {} - void SetServerAcceptor(); + void SetServerCallDestination(); CallInitiator CreateCall(ClientMetadataHandle client_initial_metadata); std::string RandomString(int min_length, int max_length, @@ -270,18 +271,14 @@ class TransportTest : public ::testing::Test { void Timeout(); - class Acceptor final : public ServerTransport::Acceptor { + class ServerCallDestination final : public UnstartedCallDestination { public: - explicit Acceptor(TransportTest* test) : test_(test) {} - - Arena* CreateArena() override; - absl::StatusOr CreateCall( - ClientMetadataHandle client_initial_metadata, Arena* arena) override; + void StartCall(UnstartedCallHandler unstarted_call_handler) override; + void Orphaned() override {} absl::optional PopHandler(); private: std::queue handlers_; - TransportTest* const test_; }; class WatchDog { @@ -296,6 +293,7 @@ class TransportTest : public ::testing::Test { [this]() { test_->Timeout(); })}; }; + grpc::testing::TestGrpcScope grpc_scope_; std::shared_ptr event_engine_{ std::make_shared( @@ -313,7 +311,8 @@ class TransportTest : public ::testing::Test { ->memory_quota() ->CreateMemoryAllocator("test-allocator"), 1024)}; - Acceptor acceptor_{this}; + RefCountedPtr server_call_destination_ = + MakeRefCounted(); TransportFixture::ClientAndServerTransportPair transport_pair_ = fixture_->CreateTransportPair(event_engine_); std::queue> diff --git a/test/core/tsi/BUILD b/test/core/tsi/BUILD index ac8204ced28..f139e18b655 100644 --- a/test/core/tsi/BUILD +++ b/test/core/tsi/BUILD @@ -91,7 +91,7 @@ grpc_cc_test( grpc_cc_test( name = "ssl_transport_security_test", - timeout = "long", + timeout = "eternal", srcs = ["ssl_transport_security_test.cc"], data = [ "//src/core/tsi/test_creds:badclient.key", diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc index 0e6a5aa162a..ff1e0dcfa58 100644 --- a/test/core/tsi/ssl_transport_security_test.cc +++ b/test/core/tsi/ssl_transport_security_test.cc @@ -34,9 +34,7 @@ #include #include -#include "src/core/lib/gprpp/crash.h" #include "src/core/lib/gprpp/memory.h" -#include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/transport_security.h" #include "src/core/tsi/transport_security_interface.h" #include "test/core/test_util/build.h" @@ -63,10 +61,6 @@ const size_t kSessionTicketEncryptionKeySize = 80; const size_t kSessionTicketEncryptionKeySize = 48; #endif -// Indicates the TLS version used for the test. -static tsi_tls_version test_tls_version = tsi_tls_version::TSI_TLS1_3; -static bool test_send_client_ca_list = false; - typedef enum AlpnMode { NO_ALPN, ALPN_CLIENT_NO_SERVER, @@ -102,215 +96,9 @@ typedef struct ssl_key_cert_lib { uint16_t leaf_signed_by_intermediate_num_key_cert_pairs; } ssl_key_cert_lib; -typedef struct ssl_tsi_test_fixture { - tsi_test_fixture base; - ssl_key_cert_lib* key_cert_lib; - ssl_alpn_lib* alpn_lib; - bool force_client_auth; - char* server_name_indication; - tsi_ssl_session_cache* session_cache; - bool session_reused; - const char* session_ticket_key; - size_t session_ticket_key_size; - size_t network_bio_buf_size; - size_t ssl_bio_buf_size; - bool verify_root_cert_subject; - tsi_ssl_server_handshaker_factory* server_handshaker_factory; - tsi_ssl_client_handshaker_factory* client_handshaker_factory; -} ssl_tsi_test_fixture; - -static void ssl_test_setup_handshakers(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->key_cert_lib, nullptr); - ASSERT_NE(ssl_fixture->alpn_lib, nullptr); - ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - // Create client handshaker factory. - tsi_ssl_client_handshaker_options client_options; - if (key_cert_lib->use_pem_root_certs) { - client_options.pem_root_certs = key_cert_lib->root_cert; - } - if (ssl_fixture->force_client_auth) { - client_options.pem_key_cert_pair = - key_cert_lib->use_bad_client_cert - ? &key_cert_lib->bad_client_pem_key_cert_pair - : &key_cert_lib->client_pem_key_cert_pair; - } - if (alpn_lib->alpn_mode == ALPN_CLIENT_NO_SERVER || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - client_options.alpn_protocols = alpn_lib->client_alpn_protocols; - client_options.num_alpn_protocols = alpn_lib->num_client_alpn_protocols; - } - client_options.root_store = - key_cert_lib->use_root_store ? key_cert_lib->root_store : nullptr; - if (ssl_fixture->session_cache != nullptr) { - client_options.session_cache = ssl_fixture->session_cache; - } - client_options.min_tls_version = test_tls_version; - client_options.max_tls_version = test_tls_version; - client_options.skip_server_certificate_verification = - key_cert_lib->skip_server_certificate_verification; - ASSERT_EQ(tsi_create_ssl_client_handshaker_factory_with_options( - &client_options, &ssl_fixture->client_handshaker_factory), - TSI_OK); - // Create server handshaker factory. - tsi_ssl_server_handshaker_options server_options; - if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || - alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - server_options.alpn_protocols = alpn_lib->server_alpn_protocols; - server_options.num_alpn_protocols = alpn_lib->num_server_alpn_protocols; - if (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { - server_options.num_alpn_protocols--; - } - } - if (key_cert_lib->use_cert_signed_by_intermediate_ca) { - server_options.pem_key_cert_pairs = - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs; - server_options.num_key_cert_pairs = - key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs; - } else { - server_options.pem_key_cert_pairs = - key_cert_lib->use_bad_server_cert - ? key_cert_lib->bad_server_pem_key_cert_pairs - : key_cert_lib->server_pem_key_cert_pairs; - server_options.num_key_cert_pairs = - key_cert_lib->use_bad_server_cert - ? key_cert_lib->bad_server_num_key_cert_pairs - : key_cert_lib->server_num_key_cert_pairs; - } - server_options.pem_client_root_certs = key_cert_lib->root_cert; - if (ssl_fixture->force_client_auth) { - server_options.client_certificate_request = - TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; - } else { - server_options.client_certificate_request = - TSI_DONT_REQUEST_CLIENT_CERTIFICATE; - } - server_options.send_client_ca_list = test_send_client_ca_list; - server_options.session_ticket_key = ssl_fixture->session_ticket_key; - server_options.session_ticket_key_size = ssl_fixture->session_ticket_key_size; - server_options.min_tls_version = test_tls_version; - server_options.max_tls_version = test_tls_version; - ASSERT_EQ(tsi_create_ssl_server_handshaker_factory_with_options( - &server_options, &ssl_fixture->server_handshaker_factory), - TSI_OK); - // Create server and client handshakers. - ASSERT_EQ( - tsi_ssl_client_handshaker_factory_create_handshaker( - ssl_fixture->client_handshaker_factory, - ssl_fixture->server_name_indication, - ssl_fixture->network_bio_buf_size, ssl_fixture->ssl_bio_buf_size, - &ssl_fixture->base.client_handshaker), - TSI_OK); - ASSERT_EQ( - tsi_ssl_server_handshaker_factory_create_handshaker( - ssl_fixture->server_handshaker_factory, - ssl_fixture->network_bio_buf_size, ssl_fixture->ssl_bio_buf_size, - &ssl_fixture->base.server_handshaker), - TSI_OK); -} - -static void check_verified_root_cert_subject( - ssl_tsi_test_fixture* /*ssl_fixture*/, const tsi_peer* peer) { - const tsi_peer_property* verified_root_cert_subject = - tsi_peer_get_property_by_name( - peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); - ASSERT_NE(verified_root_cert_subject, nullptr); - const char* expected_match = - "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"; - ASSERT_EQ(memcmp(verified_root_cert_subject->value.data, expected_match, - verified_root_cert_subject->value.length), - 0); -} - -static void check_verified_root_cert_subject_unset( - ssl_tsi_test_fixture* /*ssl_fixture*/, const tsi_peer* peer) { - const tsi_peer_property* verified_root_cert_subject = - tsi_peer_get_property_by_name( - peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); - ASSERT_EQ(verified_root_cert_subject, nullptr); -} - -static void check_alpn(ssl_tsi_test_fixture* ssl_fixture, - const tsi_peer* peer) { - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->alpn_lib, nullptr); - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - const tsi_peer_property* alpn_property = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (alpn_lib->alpn_mode != ALPN_CLIENT_SERVER_OK) { - ASSERT_EQ(alpn_property, nullptr); - } else { - ASSERT_NE(alpn_property, nullptr); - const char* expected_match = "baz"; - ASSERT_EQ(memcmp(alpn_property->value.data, expected_match, - alpn_property->value.length), - 0); - } -} - -static void check_security_level(const tsi_peer* peer) { - const tsi_peer_property* security_level = - tsi_peer_get_property_by_name(peer, TSI_SECURITY_LEVEL_PEER_PROPERTY); - ASSERT_NE(security_level, nullptr); - const char* expected_match = "TSI_PRIVACY_AND_INTEGRITY"; - ASSERT_EQ(memcmp(security_level->value.data, expected_match, - security_level->value.length), - 0); -} - -static const tsi_peer_property* -check_basic_authenticated_peer_and_get_common_name(const tsi_peer* peer) { - const tsi_peer_property* cert_type_property = - tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY); - EXPECT_NE(cert_type_property, nullptr); - EXPECT_EQ(memcmp(cert_type_property->value.data, TSI_X509_CERTIFICATE_TYPE, - cert_type_property->value.length), - 0); - const tsi_peer_property* property = tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); - EXPECT_NE(property, nullptr); - return property; -} - -static void check_session_reusage(ssl_tsi_test_fixture* ssl_fixture, - tsi_peer* peer) { - const tsi_peer_property* session_reused = - tsi_peer_get_property_by_name(peer, TSI_SSL_SESSION_REUSED_PEER_PROPERTY); - ASSERT_NE(session_reused, nullptr); - if (ssl_fixture->session_reused) { - ASSERT_EQ(strncmp(session_reused->value.data, "true", - session_reused->value.length), - 0); - } else { - ASSERT_EQ(strncmp(session_reused->value.data, "false", - session_reused->value.length), - 0); - } -} - -void check_server0_peer(tsi_peer* peer) { - const tsi_peer_property* property = - check_basic_authenticated_peer_and_get_common_name(peer); - const char* expected_match = "*.test.google.com.au"; - ASSERT_EQ( - memcmp(property->value.data, expected_match, property->value.length), 0); - ASSERT_EQ(tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY), - nullptr); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "BAR.TEST.GOOGLE.COM.AU"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "Bar.Test.Google.Com.Au"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bAr.TeST.gOOgle.cOm.AU"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.blah"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.com.au"), 0); - tsi_peer_destruct(peer); +static void ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp) { + gpr_free(const_cast(kp.private_key)); + gpr_free(const_cast(kp.cert_chain)); } static bool check_property(tsi_peer* peer, const char* property_name, @@ -327,183 +115,6 @@ static bool check_property(tsi_peer* peer, const char* property_name, return false; } -void check_server1_peer(tsi_peer* peer) { - const tsi_peer_property* property = - check_basic_authenticated_peer_and_get_common_name(peer); - const char* expected_match = "*.test.google.com"; - ASSERT_EQ( - memcmp(property->value.data, expected_match, property->value.length), 0); - ASSERT_EQ( - check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, - "*.test.google.fr"), - 1); - ASSERT_EQ( - check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, - "waterzooi.test.google.be"), - 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.fr"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.fr"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com"), 1); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.fr"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.test.google.be"), 0); - ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.youtube.com"), 0); - tsi_peer_destruct(peer); -} - -static void check_client_peer(ssl_tsi_test_fixture* ssl_fixture, - tsi_peer* peer) { - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->alpn_lib, nullptr); - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - if (!ssl_fixture->force_client_auth) { - ASSERT_EQ(peer->property_count, - (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ? 3 : 2)); - } else { - const tsi_peer_property* property = - check_basic_authenticated_peer_and_get_common_name(peer); - const char* expected_match = "testclient"; - ASSERT_EQ( - memcmp(property->value.data, expected_match, property->value.length), - 0); - } - tsi_peer_destruct(peer); -} - -static void ssl_test_check_handshaker_peers(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ASSERT_NE(ssl_fixture, nullptr); - ASSERT_NE(ssl_fixture->key_cert_lib, nullptr); - ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; - tsi_peer peer; - // In TLS 1.3, the client-side handshake succeeds even if the client sends a - // bad certificate. In such a case, the server would fail the TLS handshake - // and send an alert to the client as the first application data message. In - // TLS 1.2, the client-side handshake will fail if the client sends a bad - // certificate. - // - // For OpenSSL versions < 1.1, TLS 1.3 is not supported, so the client-side - // handshake should succeed precisely when the server-side handshake - // succeeds. - bool expect_server_success = - !(key_cert_lib->use_bad_server_cert || - (key_cert_lib->use_bad_client_cert && ssl_fixture->force_client_auth)); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - bool expect_client_success = test_tls_version == tsi_tls_version::TSI_TLS1_2 - ? expect_server_success - : !key_cert_lib->use_bad_server_cert; -#else - bool expect_client_success = expect_server_success; -#endif - if (expect_client_success) { - ASSERT_EQ(tsi_handshaker_result_extract_peer( - ssl_fixture->base.client_result, &peer), - TSI_OK); - check_session_reusage(ssl_fixture, &peer); - check_alpn(ssl_fixture, &peer); - check_security_level(&peer); - if (ssl_fixture->verify_root_cert_subject) { - if (!ssl_fixture->session_reused) { - check_verified_root_cert_subject(ssl_fixture, &peer); - } else { - check_verified_root_cert_subject_unset(ssl_fixture, &peer); - } - } - if (ssl_fixture->server_name_indication == nullptr || - strcmp(ssl_fixture->server_name_indication, SSL_TSI_TEST_WRONG_SNI) == - 0 || - strcmp(ssl_fixture->server_name_indication, SSL_TSI_TEST_INVALID_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 { - ASSERT_EQ(ssl_fixture->base.client_result, nullptr); - } - if (expect_server_success) { - ASSERT_EQ(tsi_handshaker_result_extract_peer( - ssl_fixture->base.server_result, &peer), - TSI_OK); - check_session_reusage(ssl_fixture, &peer); - check_alpn(ssl_fixture, &peer); - check_security_level(&peer); - if (ssl_fixture->force_client_auth && !ssl_fixture->session_reused) { - check_verified_root_cert_subject(ssl_fixture, &peer); - } else { - check_verified_root_cert_subject_unset(ssl_fixture, &peer); - } - check_client_peer(ssl_fixture, &peer); - } else { - ASSERT_EQ(ssl_fixture->base.server_result, nullptr); - } -} - -static void ssl_test_pem_key_cert_pair_destroy(tsi_ssl_pem_key_cert_pair kp) { - gpr_free(const_cast(kp.private_key)); - gpr_free(const_cast(kp.cert_chain)); -} - -static void ssl_test_destruct(tsi_test_fixture* fixture) { - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - if (ssl_fixture == nullptr) { - return; - } - // Destroy ssl_alpn_lib. - ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib; - for (size_t i = 0; i < alpn_lib->num_server_alpn_protocols; i++) { - gpr_free(const_cast(alpn_lib->server_alpn_protocols[i])); - } - gpr_free(alpn_lib->server_alpn_protocols); - for (size_t i = 0; i < alpn_lib->num_client_alpn_protocols; i++) { - gpr_free(const_cast(alpn_lib->client_alpn_protocols[i])); - } - gpr_free(alpn_lib->client_alpn_protocols); - gpr_free(alpn_lib); - // Destroy ssl_key_cert_lib. - ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib; - for (size_t i = 0; i < key_cert_lib->server_num_key_cert_pairs; i++) { - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->server_pem_key_cert_pairs[i]); - } - gpr_free(key_cert_lib->server_pem_key_cert_pairs); - for (size_t i = 0; i < key_cert_lib->bad_server_num_key_cert_pairs; i++) { - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->bad_server_pem_key_cert_pairs[i]); - } - gpr_free(key_cert_lib->bad_server_pem_key_cert_pairs); - for (size_t i = 0; - i < key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs; i++) { - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs[i]); - } - gpr_free(key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs); - ssl_test_pem_key_cert_pair_destroy(key_cert_lib->client_pem_key_cert_pair); - ssl_test_pem_key_cert_pair_destroy( - key_cert_lib->bad_client_pem_key_cert_pair); - gpr_free(key_cert_lib->root_cert); - tsi_ssl_root_certs_store_destroy(key_cert_lib->root_store); - gpr_free(key_cert_lib); - if (ssl_fixture->session_cache != nullptr) { - tsi_ssl_session_cache_unref(ssl_fixture->session_cache); - } - // Unreference others. - tsi_ssl_server_handshaker_factory_unref( - ssl_fixture->server_handshaker_factory); - tsi_ssl_client_handshaker_factory_unref( - ssl_fixture->client_handshaker_factory); - gpr_free(ssl_fixture); -} - -static const struct tsi_test_fixture_vtable vtable = { - ssl_test_setup_handshakers, ssl_test_check_handshaker_peers, - ssl_test_destruct}; - static char* load_file(std::string path) { std::string data = grpc_core::testing::GetFileContents(path); return gpr_strdup(data.c_str()); @@ -535,310 +146,756 @@ static std::string GenerateTrustBundle() { return trust_bundle; } -static tsi_test_fixture* ssl_tsi_test_fixture_create() { - ssl_tsi_test_fixture* ssl_fixture = grpc_core::Zalloc(); - tsi_test_fixture_init(&ssl_fixture->base); - ssl_fixture->verify_root_cert_subject = true; - ssl_fixture->base.test_unused_bytes = true; - ssl_fixture->base.vtable = &vtable; - // Create ssl_key_cert_lib. - ssl_key_cert_lib* key_cert_lib = grpc_core::Zalloc(); - key_cert_lib->use_bad_server_cert = false; - key_cert_lib->use_bad_client_cert = false; - key_cert_lib->use_root_store = false; - key_cert_lib->use_pem_root_certs = true; - key_cert_lib->skip_server_certificate_verification = false; - key_cert_lib->server_num_key_cert_pairs = - SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM; - key_cert_lib->bad_server_num_key_cert_pairs = - SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM; - key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs = - SSL_TSI_TEST_LEAF_SIGNED_BY_INTERMEDIATE_KEY_CERT_PAIRS_NUM; - key_cert_lib->server_pem_key_cert_pairs = - static_cast( - gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * - key_cert_lib->server_num_key_cert_pairs)); - key_cert_lib->bad_server_pem_key_cert_pairs = - static_cast( - gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * - key_cert_lib->bad_server_num_key_cert_pairs)); - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs = - static_cast(gpr_malloc( - sizeof(tsi_ssl_pem_key_cert_pair) * - key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs)); - key_cert_lib->server_pem_key_cert_pairs[0].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.key"); - key_cert_lib->server_pem_key_cert_pairs[0].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.pem"); - key_cert_lib->server_pem_key_cert_pairs[1].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.key"); - key_cert_lib->server_pem_key_cert_pairs[1].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.pem"); - key_cert_lib->bad_server_pem_key_cert_pairs[0].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.key"); - key_cert_lib->bad_server_pem_key_cert_pairs[0].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.pem"); - key_cert_lib->client_pem_key_cert_pair.private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.key"); - key_cert_lib->client_pem_key_cert_pair.cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.pem"); - key_cert_lib->bad_client_pem_key_cert_pair.private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.key"); - key_cert_lib->bad_client_pem_key_cert_pair.cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.pem"); - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs[0].private_key = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "leaf_signed_by_intermediate.key"); - key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs[0].cert_chain = - load_file(SSL_TSI_TEST_CREDENTIALS_DIR "leaf_and_intermediate_chain.pem"); - key_cert_lib->root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); - key_cert_lib->root_store = - tsi_ssl_root_certs_store_create(key_cert_lib->root_cert); - EXPECT_NE(key_cert_lib->root_store, nullptr); - ssl_fixture->key_cert_lib = key_cert_lib; - // Create ssl_alpn_lib. - ssl_alpn_lib* alpn_lib = grpc_core::Zalloc(); - alpn_lib->server_alpn_protocols = static_cast( - gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); - alpn_lib->client_alpn_protocols = static_cast( - gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); - alpn_lib->server_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN1); - alpn_lib->server_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); - alpn_lib->client_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN2); - alpn_lib->client_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); - alpn_lib->num_server_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; - alpn_lib->num_client_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; - alpn_lib->alpn_mode = NO_ALPN; - ssl_fixture->alpn_lib = alpn_lib; - ssl_fixture->base.vtable = &vtable; - ssl_fixture->server_name_indication = nullptr; - ssl_fixture->session_reused = false; - ssl_fixture->session_ticket_key = nullptr; - ssl_fixture->session_ticket_key_size = 0; - ssl_fixture->force_client_auth = false; - ssl_fixture->network_bio_buf_size = 0; - ssl_fixture->ssl_bio_buf_size = 0; - return &ssl_fixture->base; -} +class SslTransportSecurityTest + : public ::testing::TestWithParam> { + protected: + // A tsi_test_fixture implementation + class SslTsiTestFixture { + public: + SslTsiTestFixture(tsi_tls_version tls_version, bool send_client_ca_list) { + tsi_test_fixture_init(&base_); + verify_root_cert_subject_ = true; + base_.test_unused_bytes = true; + base_.vtable = &kVtable; + // Create ssl_key_cert_lib. + key_cert_lib_ = grpc_core::Zalloc(); + key_cert_lib_->use_bad_server_cert = false; + key_cert_lib_->use_bad_client_cert = false; + key_cert_lib_->use_root_store = false; + key_cert_lib_->use_pem_root_certs = true; + key_cert_lib_->skip_server_certificate_verification = false; + key_cert_lib_->server_num_key_cert_pairs = + SSL_TSI_TEST_SERVER_KEY_CERT_PAIRS_NUM; + key_cert_lib_->bad_server_num_key_cert_pairs = + SSL_TSI_TEST_BAD_SERVER_KEY_CERT_PAIRS_NUM; + key_cert_lib_->leaf_signed_by_intermediate_num_key_cert_pairs = + SSL_TSI_TEST_LEAF_SIGNED_BY_INTERMEDIATE_KEY_CERT_PAIRS_NUM; + key_cert_lib_->server_pem_key_cert_pairs = + static_cast( + gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * + key_cert_lib_->server_num_key_cert_pairs)); + key_cert_lib_->bad_server_pem_key_cert_pairs = + static_cast( + gpr_malloc(sizeof(tsi_ssl_pem_key_cert_pair) * + key_cert_lib_->bad_server_num_key_cert_pairs)); + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs = + static_cast(gpr_malloc( + sizeof(tsi_ssl_pem_key_cert_pair) * + key_cert_lib_->leaf_signed_by_intermediate_num_key_cert_pairs)); + key_cert_lib_->server_pem_key_cert_pairs[0].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.key"); + key_cert_lib_->server_pem_key_cert_pairs[0].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server0.pem"); + key_cert_lib_->server_pem_key_cert_pairs[1].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.key"); + key_cert_lib_->server_pem_key_cert_pairs[1].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.pem"); + key_cert_lib_->bad_server_pem_key_cert_pairs[0].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.key"); + key_cert_lib_->bad_server_pem_key_cert_pairs[0].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badserver.pem"); + key_cert_lib_->client_pem_key_cert_pair.private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.key"); + key_cert_lib_->client_pem_key_cert_pair.cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.pem"); + key_cert_lib_->bad_client_pem_key_cert_pair.private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.key"); + key_cert_lib_->bad_client_pem_key_cert_pair.cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "badclient.pem"); + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs[0].private_key = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR + "leaf_signed_by_intermediate.key"); + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs[0].cert_chain = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR + "leaf_and_intermediate_chain.pem"); + key_cert_lib_->root_cert = + load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); + key_cert_lib_->root_store = + tsi_ssl_root_certs_store_create(key_cert_lib_->root_cert); + EXPECT_NE(key_cert_lib_->root_store, nullptr); + // Create ssl_alpn_lib. + alpn_lib_ = grpc_core::Zalloc(); + alpn_lib_->server_alpn_protocols = static_cast( + gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); + alpn_lib_->client_alpn_protocols = static_cast( + gpr_zalloc(sizeof(char*) * SSL_TSI_TEST_ALPN_NUM)); + alpn_lib_->server_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN1); + alpn_lib_->server_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); + alpn_lib_->client_alpn_protocols[0] = gpr_strdup(SSL_TSI_TEST_ALPN2); + alpn_lib_->client_alpn_protocols[1] = gpr_strdup(SSL_TSI_TEST_ALPN3); + alpn_lib_->num_server_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; + alpn_lib_->num_client_alpn_protocols = SSL_TSI_TEST_ALPN_NUM; + alpn_lib_->alpn_mode = NO_ALPN; + server_name_indication_ = nullptr; + session_reused_ = false; + session_ticket_key_ = nullptr; + session_ticket_key_size_ = 0; + force_client_auth_ = false; + network_bio_buf_size_ = 0; + ssl_bio_buf_size_ = 0; + send_client_ca_list_ = send_client_ca_list; + tls_version_ = tls_version; + } + + ~SslTsiTestFixture() { + // Destroy ssl_alpn_lib. + for (size_t i = 0; i < alpn_lib_->num_server_alpn_protocols; i++) { + gpr_free(const_cast(alpn_lib_->server_alpn_protocols[i])); + } + gpr_free(alpn_lib_->server_alpn_protocols); + for (size_t i = 0; i < alpn_lib_->num_client_alpn_protocols; i++) { + gpr_free(const_cast(alpn_lib_->client_alpn_protocols[i])); + } + gpr_free(alpn_lib_->client_alpn_protocols); + gpr_free(alpn_lib_); + // Destroy ssl_key_cert_lib. + for (size_t i = 0; i < key_cert_lib_->server_num_key_cert_pairs; i++) { + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->server_pem_key_cert_pairs[i]); + } + gpr_free(key_cert_lib_->server_pem_key_cert_pairs); + for (size_t i = 0; i < key_cert_lib_->bad_server_num_key_cert_pairs; + i++) { + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->bad_server_pem_key_cert_pairs[i]); + } + gpr_free(key_cert_lib_->bad_server_pem_key_cert_pairs); + for (size_t i = 0; + i < key_cert_lib_->leaf_signed_by_intermediate_num_key_cert_pairs; + i++) { + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs[i]); + } + gpr_free(key_cert_lib_->leaf_signed_by_intermediate_key_cert_pairs); + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->client_pem_key_cert_pair); + ssl_test_pem_key_cert_pair_destroy( + key_cert_lib_->bad_client_pem_key_cert_pair); + gpr_free(key_cert_lib_->root_cert); + tsi_ssl_root_certs_store_destroy(key_cert_lib_->root_store); + gpr_free(key_cert_lib_); + if (session_cache_ != nullptr) { + tsi_ssl_session_cache_unref(session_cache_); + } + // Unreference others. + tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); + tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); + } + + tsi_test_fixture* GetBaseFixture() { return &base_; } + + void SetVerifyRootCertSubject(bool verify_root_cert_subject) { + verify_root_cert_subject_ = verify_root_cert_subject; + } + + ssl_key_cert_lib* MutableKeyCertLib() { return key_cert_lib_; } + + void SetForceClientAuth(bool force_client_auth) { + force_client_auth_ = force_client_auth; + } + + void SetAlpnMode(AlpnMode alpn_mode) { alpn_lib_->alpn_mode = alpn_mode; } + + void SetServerNameIndication(char* server_name_indication) { + server_name_indication_ = server_name_indication; + } + + void SetSessionCache(tsi_ssl_session_cache* cache) { + session_cache_ = cache; + } + + void SetSessionReused(bool session_reused) { + session_reused_ = session_reused; + } + + void SetSessionTicketKey(const char* session_ticket_key, + size_t session_ticket_key_size) { + session_ticket_key_ = session_ticket_key; + session_ticket_key_size_ = session_ticket_key_size; + } + + void SetBioBufSizes(size_t network_bio_buf_size, size_t ssl_bio_buf_size) { + network_bio_buf_size_ = network_bio_buf_size; + ssl_bio_buf_size_ = ssl_bio_buf_size; + } + + private: + static void SetupHandshakers(tsi_test_fixture* fixture) { + SslTsiTestFixture* ssl_fixture = + reinterpret_cast(fixture); + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->key_cert_lib_, nullptr); + ASSERT_NE(ssl_fixture->alpn_lib_, nullptr); + ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib_; + ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib_; + // Create client handshaker factory. + tsi_ssl_client_handshaker_options client_options; + if (key_cert_lib->use_pem_root_certs) { + client_options.pem_root_certs = key_cert_lib->root_cert; + } + if (ssl_fixture->force_client_auth_) { + client_options.pem_key_cert_pair = + key_cert_lib->use_bad_client_cert + ? &key_cert_lib->bad_client_pem_key_cert_pair + : &key_cert_lib->client_pem_key_cert_pair; + } + if (alpn_lib->alpn_mode == ALPN_CLIENT_NO_SERVER || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { + client_options.alpn_protocols = alpn_lib->client_alpn_protocols; + client_options.num_alpn_protocols = alpn_lib->num_client_alpn_protocols; + } + client_options.root_store = + key_cert_lib->use_root_store ? key_cert_lib->root_store : nullptr; + if (ssl_fixture->session_cache_ != nullptr) { + client_options.session_cache = ssl_fixture->session_cache_; + } + client_options.min_tls_version = ssl_fixture->tls_version_; + client_options.max_tls_version = ssl_fixture->tls_version_; + client_options.skip_server_certificate_verification = + key_cert_lib->skip_server_certificate_verification; + ASSERT_EQ(tsi_create_ssl_client_handshaker_factory_with_options( + &client_options, &ssl_fixture->client_handshaker_factory_), + TSI_OK); + // Create server handshaker factory. + tsi_ssl_server_handshaker_options server_options; + if (alpn_lib->alpn_mode == ALPN_SERVER_NO_CLIENT || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK || + alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { + server_options.alpn_protocols = alpn_lib->server_alpn_protocols; + server_options.num_alpn_protocols = alpn_lib->num_server_alpn_protocols; + if (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_MISMATCH) { + server_options.num_alpn_protocols--; + } + } + if (key_cert_lib->use_cert_signed_by_intermediate_ca) { + server_options.pem_key_cert_pairs = + key_cert_lib->leaf_signed_by_intermediate_key_cert_pairs; + server_options.num_key_cert_pairs = + key_cert_lib->leaf_signed_by_intermediate_num_key_cert_pairs; + } else { + server_options.pem_key_cert_pairs = + key_cert_lib->use_bad_server_cert + ? key_cert_lib->bad_server_pem_key_cert_pairs + : key_cert_lib->server_pem_key_cert_pairs; + server_options.num_key_cert_pairs = + key_cert_lib->use_bad_server_cert + ? key_cert_lib->bad_server_num_key_cert_pairs + : key_cert_lib->server_num_key_cert_pairs; + } + server_options.pem_client_root_certs = key_cert_lib->root_cert; + if (ssl_fixture->force_client_auth_) { + server_options.client_certificate_request = + TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; + } else { + server_options.client_certificate_request = + TSI_DONT_REQUEST_CLIENT_CERTIFICATE; + } + server_options.send_client_ca_list = ssl_fixture->send_client_ca_list_; + server_options.session_ticket_key = ssl_fixture->session_ticket_key_; + server_options.session_ticket_key_size = + ssl_fixture->session_ticket_key_size_; + server_options.min_tls_version = ssl_fixture->tls_version_; + server_options.max_tls_version = ssl_fixture->tls_version_; + ASSERT_EQ(tsi_create_ssl_server_handshaker_factory_with_options( + &server_options, &ssl_fixture->server_handshaker_factory_), + TSI_OK); + // Create server and client handshakers. + ASSERT_EQ(tsi_ssl_client_handshaker_factory_create_handshaker( + ssl_fixture->client_handshaker_factory_, + ssl_fixture->server_name_indication_, + ssl_fixture->network_bio_buf_size_, + ssl_fixture->ssl_bio_buf_size_, + &ssl_fixture->base_.client_handshaker), + TSI_OK); + ASSERT_EQ(tsi_ssl_server_handshaker_factory_create_handshaker( + ssl_fixture->server_handshaker_factory_, + ssl_fixture->network_bio_buf_size_, + ssl_fixture->ssl_bio_buf_size_, + &ssl_fixture->base_.server_handshaker), + TSI_OK); + } + + static void CheckAlpn(SslTsiTestFixture* ssl_fixture, + const tsi_peer* peer) { + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->alpn_lib_, nullptr); + ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib_; + const tsi_peer_property* alpn_property = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (alpn_lib->alpn_mode != ALPN_CLIENT_SERVER_OK) { + ASSERT_EQ(alpn_property, nullptr); + } else { + ASSERT_NE(alpn_property, nullptr); + const char* expected_match = "baz"; + ASSERT_EQ(memcmp(alpn_property->value.data, expected_match, + alpn_property->value.length), + 0); + } + } + + static void CheckSecurityLevel(const tsi_peer* peer) { + const tsi_peer_property* security_level = + tsi_peer_get_property_by_name(peer, TSI_SECURITY_LEVEL_PEER_PROPERTY); + ASSERT_NE(security_level, nullptr); + const char* expected_match = "TSI_PRIVACY_AND_INTEGRITY"; + ASSERT_EQ(memcmp(security_level->value.data, expected_match, + security_level->value.length), + 0); + } + + static const tsi_peer_property* CheckBasicAuthenticatedPeerAndGetCommonName( + const tsi_peer* peer) { + const tsi_peer_property* cert_type_property = + tsi_peer_get_property_by_name(peer, + TSI_CERTIFICATE_TYPE_PEER_PROPERTY); + EXPECT_NE(cert_type_property, nullptr); + EXPECT_EQ( + memcmp(cert_type_property->value.data, TSI_X509_CERTIFICATE_TYPE, + cert_type_property->value.length), + 0); + const tsi_peer_property* property = tsi_peer_get_property_by_name( + peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); + EXPECT_NE(property, nullptr); + return property; + } + + static void CheckSessionReusage(SslTsiTestFixture* ssl_fixture, + tsi_peer* peer) { + const tsi_peer_property* session_reused = tsi_peer_get_property_by_name( + peer, TSI_SSL_SESSION_REUSED_PEER_PROPERTY); + ASSERT_NE(session_reused, nullptr); + if (ssl_fixture->session_reused_) { + ASSERT_EQ(strncmp(session_reused->value.data, "true", + session_reused->value.length), + 0); + } else { + ASSERT_EQ(strncmp(session_reused->value.data, "false", + session_reused->value.length), + 0); + } + } + + // This is tied specifically to server0.pem loaded by the fixture. + static void CheckServer0Peer(tsi_peer* peer) { + const tsi_peer_property* property = + CheckBasicAuthenticatedPeerAndGetCommonName(peer); + const char* expected_match = "*.test.google.com.au"; + ASSERT_EQ( + memcmp(property->value.data, expected_match, property->value.length), + 0); + ASSERT_EQ(tsi_peer_get_property_by_name( + peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY), + nullptr); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.com.au"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.com.au"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "BAR.TEST.GOOGLE.COM.AU"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "Bar.Test.Google.Com.Au"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bAr.TeST.gOOgle.cOm.AU"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.blah"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.bar.test.google.com.au"), + 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.com.au"), 0); + tsi_peer_destruct(peer); + } + + // This is tied specifically to server1.pem loaded by the fixture. + static void CheckServer1Peer(tsi_peer* peer) { + const tsi_peer_property* property = + CheckBasicAuthenticatedPeerAndGetCommonName(peer); + const char* expected_match = "*.test.google.com"; + ASSERT_EQ( + memcmp(property->value.data, expected_match, property->value.length), + 0); + ASSERT_EQ( + check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, + "*.test.google.fr"), + 1); + ASSERT_EQ( + check_property(peer, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, + "waterzooi.test.google.be"), + 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.google.fr"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.test.google.fr"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "waterzooi.test.google.be"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "foo.test.youtube.com"), 1); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "bar.foo.test.google.com"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "test.google.fr"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.test.google.be"), 0); + ASSERT_EQ(tsi_ssl_peer_matches_name(peer, "tartines.youtube.com"), 0); + tsi_peer_destruct(peer); + } + + static void CheckClientPeer(SslTsiTestFixture* ssl_fixture, + tsi_peer* peer) { + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->alpn_lib_, nullptr); + ssl_alpn_lib* alpn_lib = ssl_fixture->alpn_lib_; + if (!ssl_fixture->force_client_auth_) { + ASSERT_EQ(peer->property_count, + (alpn_lib->alpn_mode == ALPN_CLIENT_SERVER_OK ? 3 : 2)); + } else { + const tsi_peer_property* property = + CheckBasicAuthenticatedPeerAndGetCommonName(peer); + const char* expected_match = "testclient"; + ASSERT_EQ(memcmp(property->value.data, expected_match, + property->value.length), + 0); + } + tsi_peer_destruct(peer); + } + + static void CheckVerifiedRootCertSubject(const tsi_peer* peer) { + const tsi_peer_property* verified_root_cert_subject = + tsi_peer_get_property_by_name( + peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); + ASSERT_NE(verified_root_cert_subject, nullptr); + const char* expected_match = + "CN=testca,O=Internet Widgits Pty Ltd,ST=Some-State,C=AU"; + ASSERT_EQ(memcmp(verified_root_cert_subject->value.data, expected_match, + verified_root_cert_subject->value.length), + 0); + } + + static void CheckVerifiedRootCertSubjectUnset(const tsi_peer* peer) { + const tsi_peer_property* verified_root_cert_subject = + tsi_peer_get_property_by_name( + peer, TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY); + ASSERT_EQ(verified_root_cert_subject, nullptr); + } + + static void CheckHandshakerPeers(tsi_test_fixture* fixture) { + SslTsiTestFixture* ssl_fixture = + reinterpret_cast(fixture); + ASSERT_NE(ssl_fixture, nullptr); + ASSERT_NE(ssl_fixture->key_cert_lib_, nullptr); + ssl_key_cert_lib* key_cert_lib = ssl_fixture->key_cert_lib_; + tsi_peer peer; + // In TLS 1.3, the client-side handshake succeeds even if the client sends + // a bad certificate. In such a case, the server would fail the TLS + // handshake and send an alert to the client as the first application data + // message. In TLS 1.2, the client-side handshake will fail if the client + // sends a bad certificate. + // + // For OpenSSL versions < 1.1, TLS 1.3 is not supported, so the + // client-side handshake should succeed precisely when the server-side + // handshake succeeds. + bool expect_server_success = !(key_cert_lib->use_bad_server_cert || + (key_cert_lib->use_bad_client_cert && + ssl_fixture->force_client_auth_)); +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + bool expect_client_success = + ssl_fixture->tls_version_ == tsi_tls_version::TSI_TLS1_2 + ? expect_server_success + : !key_cert_lib->use_bad_server_cert; +#else + bool expect_client_success = expect_server_success; +#endif + if (expect_client_success) { + ASSERT_EQ(tsi_handshaker_result_extract_peer( + ssl_fixture->base_.client_result, &peer), + TSI_OK); + CheckSessionReusage(ssl_fixture, &peer); + CheckAlpn(ssl_fixture, &peer); + CheckSecurityLevel(&peer); + if (ssl_fixture->verify_root_cert_subject_) { + if (!ssl_fixture->session_reused_) { + CheckVerifiedRootCertSubject(&peer); + } else { + CheckVerifiedRootCertSubjectUnset(&peer); + } + } + if (ssl_fixture->server_name_indication_ == nullptr || + strcmp(ssl_fixture->server_name_indication_, + SSL_TSI_TEST_WRONG_SNI) == 0 || + strcmp(ssl_fixture->server_name_indication_, + SSL_TSI_TEST_INVALID_SNI) == 0) { + // Expect server to use default server0.pem. + CheckServer0Peer(&peer); + } else { + // Expect server to use server1.pem. + CheckServer1Peer(&peer); + } + } else { + ASSERT_EQ(ssl_fixture->base_.client_result, nullptr); + } + if (expect_server_success) { + ASSERT_EQ(tsi_handshaker_result_extract_peer( + ssl_fixture->base_.server_result, &peer), + TSI_OK); + CheckSessionReusage(ssl_fixture, &peer); + CheckAlpn(ssl_fixture, &peer); + CheckSecurityLevel(&peer); + if (ssl_fixture->force_client_auth_ && !ssl_fixture->session_reused_) { + CheckVerifiedRootCertSubject(&peer); + } else { + CheckVerifiedRootCertSubjectUnset(&peer); + } + CheckClientPeer(ssl_fixture, &peer); + } else { + ASSERT_EQ(ssl_fixture->base_.server_result, nullptr); + } + } + + static void Destruct(tsi_test_fixture* fixture) { + auto* self = reinterpret_cast(fixture); + delete self; + } + + static tsi_test_fixture_vtable kVtable; + + tsi_test_fixture base_; + ssl_key_cert_lib* key_cert_lib_ = nullptr; + ssl_alpn_lib* alpn_lib_; + bool force_client_auth_; + char* server_name_indication_ = nullptr; + tsi_ssl_session_cache* session_cache_ = nullptr; + bool session_reused_; + const char* session_ticket_key_ = nullptr; + size_t session_ticket_key_size_; + size_t network_bio_buf_size_; + size_t ssl_bio_buf_size_; + bool verify_root_cert_subject_; + tsi_tls_version tls_version_; + bool send_client_ca_list_; + tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; + tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; + }; -void ssl_tsi_test_do_handshake_tiny_handshake_buffer() { + SslTransportSecurityTest() { grpc_init(); } + + ~SslTransportSecurityTest() override { + DestroyFixture(); + grpc_shutdown(); + } + + void SetUpSslFixture(tsi_tls_version tls_version, bool send_client_ca_list) { + ssl_fixture_ = new SslTsiTestFixture(tls_version, send_client_ca_list); + ssl_tsi_test_fixture_ = ssl_fixture_->GetBaseFixture(); + fixture_destroyed = false; + } + + void DoHandshake() { tsi_test_do_handshake(ssl_tsi_test_fixture_); } + + void DoRoundTrip() { tsi_test_do_round_trip(ssl_tsi_test_fixture_); } + + void DestroyFixture() { + if (fixture_destroyed) { + return; + } + tsi_test_fixture_destroy(ssl_tsi_test_fixture_); + fixture_destroyed = true; + } + + tsi_test_fixture* ssl_tsi_test_fixture_; + SslTsiTestFixture* ssl_fixture_; + bool fixture_destroyed = true; +}; + +tsi_test_fixture_vtable SslTransportSecurityTest::SslTsiTestFixture::kVtable = { + SslTransportSecurityTest::SslTsiTestFixture::SetupHandshakers, + SslTransportSecurityTest::SslTsiTestFixture::CheckHandshakerPeers, + SslTransportSecurityTest::SslTsiTestFixture::Destruct}; + +INSTANTIATE_TEST_SUITE_P( + SslTestGroup, SslTransportSecurityTest, + testing::Combine(testing::Values(TSI_TLS1_2, TSI_TLS1_3), + testing::Values(true, false)), + [](const testing::TestParamInfo& + info) { + return absl::StrCat( + std::get<0>(info.param) == TSI_TLS1_2 ? "tls_12" : "tls_13", "_", + std::get<1>(info.param) ? "send_client_ca_list" + : "no_send_client_ca_list"); + }); + +TEST_P(SslTransportSecurityTest, DoHandshakeTinyHandshakeBuffer) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_tiny_handshake_buffer"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - fixture->handshake_buffer_size = TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE; + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_tsi_test_fixture_->handshake_buffer_size = + TSI_TEST_TINY_HANDSHAKE_BUFFER_SIZE; // Handshake buffer is too small to hold both handshake messages and the // unused bytes. - fixture->test_unused_bytes = false; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_tsi_test_fixture_->test_unused_bytes = false; + DoHandshake(); } -void ssl_tsi_test_do_handshake_small_handshake_buffer() { +TEST_P(SslTransportSecurityTest, DoHandshakeSmallHandshakeBuffer) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_small_handshake_buffer"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - fixture->handshake_buffer_size = TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_tsi_test_fixture_->handshake_buffer_size = + TSI_TEST_SMALL_HANDSHAKE_BUFFER_SIZE; + DoHandshake(); } -void ssl_tsi_test_do_handshake() { +TEST_P(SslTransportSecurityTest, DoHandshake) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_root_store() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithRootStore) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_root_store"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->key_cert_lib->use_root_store = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->MutableKeyCertLib()->use_root_store = true; + DoHandshake(); } -void ssl_tsi_test_do_handshake_skipping_server_certificate_verification() { +// TODO(gregorycooke) - failing with OpenSSL1.0.2 +#if OPENSSL_VERSION_NUMBER >= 0x10100000 +TEST_P(SslTransportSecurityTest, + DoHandshakeSkippingServerCertificateVerification) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_skipping_server_certificate_verification"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->verify_root_cert_subject = false; - ssl_fixture->key_cert_lib->use_root_store = false; - ssl_fixture->key_cert_lib->use_pem_root_certs = false; - ssl_fixture->key_cert_lib->skip_server_certificate_verification = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetVerifyRootCertSubject(false); + ssl_key_cert_lib* key_cert_lib = ssl_fixture_->MutableKeyCertLib(); + key_cert_lib->use_root_store = false; + key_cert_lib->use_pem_root_certs = false; + key_cert_lib->skip_server_certificate_verification = true; + DoHandshake(); } +#endif -void ssl_tsi_test_do_handshake_with_large_server_handshake_messages( - const std::string& trust_bundle) { +TEST_P(SslTransportSecurityTest, DoHandshakeWithLargeServerHandshakeMessages) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_large_server_handshake_messages"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); + std::string trust_bundle = GenerateTrustBundle(); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // Force the test to read more handshake bytes from the peer than we have room // for in the BIO. The default BIO buffer size is 17kB. - fixture->handshake_buffer_size = 18000; - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); + ssl_tsi_test_fixture_->handshake_buffer_size = 18000; // Make a copy of the root cert and free the original. - std::string root_cert(ssl_fixture->key_cert_lib->root_cert); - gpr_free(ssl_fixture->key_cert_lib->root_cert); - ssl_fixture->key_cert_lib->root_cert = nullptr; + ssl_key_cert_lib* key_cert_lib = ssl_fixture_->MutableKeyCertLib(); + std::string root_cert(key_cert_lib->root_cert); + gpr_free(key_cert_lib->root_cert); + key_cert_lib->root_cert = nullptr; // Create a new root store, consisting of the root cert that is actually // needed and 200 self-signed certs. std::string effective_trust_bundle = absl::StrCat(root_cert, trust_bundle); - tsi_ssl_root_certs_store_destroy(ssl_fixture->key_cert_lib->root_store); - ssl_fixture->key_cert_lib->root_cert = - const_cast(effective_trust_bundle.c_str()); - ssl_fixture->key_cert_lib->root_store = + tsi_ssl_root_certs_store_destroy(key_cert_lib->root_store); + key_cert_lib->root_cert = const_cast(effective_trust_bundle.c_str()); + key_cert_lib->root_store = tsi_ssl_root_certs_store_create(effective_trust_bundle.c_str()); - ssl_fixture->key_cert_lib->use_root_store = true; - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); + key_cert_lib->use_root_store = true; + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); // Overwrite the root_cert pointer so that tsi_test_fixture_destroy does not // try to gpr_free it. - ssl_fixture->key_cert_lib->root_cert = nullptr; - tsi_test_fixture_destroy(fixture); + key_cert_lib->root_cert = nullptr; } -void ssl_tsi_test_do_handshake_with_client_authentication() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithClientAuthentication) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_client_authentication"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_client_authentication_and_root_store() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithClientAuthenticationAndRootStore) { gpr_log( GPR_INFO, "ssl_tsi_test_do_handshake_with_client_authentication_and_root_store"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->force_client_auth = true; - ssl_fixture->key_cert_lib->use_root_store = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetForceClientAuth(true); + ssl_fixture_->MutableKeyCertLib()->use_root_store = true; + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithServerNameIndicationExactDomain) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_server_name_indication_exact_domain"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // server1 cert contains "waterzooi.test.google.be" in SAN. - 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("waterzooi.test.google.be"); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetServerNameIndication( + const_cast("waterzooi.test.google.be")); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithServerNameIndicationWildStarDomain) { gpr_log( GPR_INFO, "ssl_tsi_test_do_handshake_with_server_name_indication_wild_star_domain"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // server1 cert contains "*.test.google.fr" in SAN. - 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("juju.test.google.fr"); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetServerNameIndication( + const_cast("juju.test.google.fr")); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_wrong_server_name_indication() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithWrongServerNameIndication) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_wrong_server_name_indication"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // 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); + ssl_fixture_->SetServerNameIndication( + const_cast(SSL_TSI_TEST_WRONG_SNI)); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_invalid_and_ignored_server_name_indication() { +TEST_P(SslTransportSecurityTest, + DoHandshakeWithInvalidAndIgnoredServerNameIndication) { gpr_log(GPR_INFO, - "ssl_tsi_test_do_handshake_with_wrong_server_name_indication"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); + "ssl_tsi_test_do_handshake_with_invalid_and_ignored_server_name_" + "indication"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); // SNI that's an IP address will be ignored. - ssl_fixture->server_name_indication = - const_cast(SSL_TSI_TEST_INVALID_SNI); - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetServerNameIndication( + const_cast(SSL_TSI_TEST_INVALID_SNI)); + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_bad_server_cert() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithBadServerCert) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_bad_server_cert"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->key_cert_lib->use_bad_server_cert = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->MutableKeyCertLib()->use_bad_server_cert = true; + DoHandshake(); } -void ssl_tsi_test_do_handshake_with_bad_client_cert() { +TEST_P(SslTransportSecurityTest, DoHandshakeWithBadClientCert) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_bad_client_cert"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->key_cert_lib->use_bad_client_cert = true; - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->MutableKeyCertLib()->use_bad_client_cert = true; + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); } -void ssl_tsi_test_do_handshake_alpn_client_no_server() { +#ifdef OPENSSL_IS_BORINGSSL +// BoringSSL and OpenSSL have different behaviors on mismatched ALPN. +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnClientNoServer) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_no_server"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_NO_SERVER; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); -} - -void ssl_tsi_test_do_handshake_alpn_server_no_client() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_server_no_client"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_SERVER_NO_CLIENT; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_CLIENT_NO_SERVER); + DoHandshake(); } -void ssl_tsi_test_do_handshake_alpn_client_server_mismatch() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_server_no_client"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_MISMATCH; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnClientServerMismatch) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_server_mismatch"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_CLIENT_SERVER_MISMATCH); + DoHandshake(); } -void ssl_tsi_test_do_handshake_alpn_client_server_ok() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_server_ok"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->alpn_lib->alpn_mode = ALPN_CLIENT_SERVER_OK; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); -} - -void ssl_tsi_test_do_round_trip_for_all_configs() { +TEST_P(SslTransportSecurityTest, DoRoundTripForAllConfigs) { gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_for_all_configs"); unsigned int* bit_array = static_cast( gpr_zalloc(sizeof(unsigned int) * TSI_TEST_NUM_OF_ARGUMENTS)); @@ -849,31 +906,30 @@ void ssl_tsi_test_do_round_trip_for_all_configs() { bit_array[ind] = (v & mask) ? 1 : 0; v <<= 1; } - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - tsi_test_frame_protector_config_destroy(ssl_fixture->base.config); - ssl_fixture->base.config = tsi_test_frame_protector_config_create( + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + tsi_test_frame_protector_config_destroy(ssl_tsi_test_fixture_->config); + ssl_tsi_test_fixture_->config = tsi_test_frame_protector_config_create( bit_array[0], bit_array[1], bit_array[2], bit_array[3], bit_array[4], bit_array[5], bit_array[6]); - tsi_test_do_round_trip(&ssl_fixture->base); - tsi_test_fixture_destroy(fixture); + DoRoundTrip(); + DestroyFixture(); } gpr_free(bit_array); } -void ssl_tsi_test_do_round_trip_with_error_on_stack() { +TEST_P(SslTransportSecurityTest, DoRoundTripWithErrorOnStack) { gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_with_error_on_stack"); // Invoke an SSL function that causes an error, and ensure the error // makes it to the stack. ASSERT_FALSE(EC_KEY_new_by_curve_name(NID_rsa)); ASSERT_NE(ERR_peek_error(), 0); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - tsi_test_do_round_trip(fixture); - tsi_test_fixture_destroy(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + DoRoundTrip(); } -void ssl_tsi_test_do_round_trip_odd_buffer_size() { +TEST_P(SslTransportSecurityTest, DoRoundTripOddBufferSize) { gpr_log(GPR_INFO, "ssl_tsi_test_do_round_trip_odd_buffer_size"); const size_t odd_sizes[] = {1025, 2051, 4103, 8207, 16409}; size_t size = sizeof(odd_sizes) / sizeof(size_t); @@ -890,14 +946,14 @@ void ssl_tsi_test_do_round_trip_odd_buffer_size() { for (size_t ind3 = 0; ind3 < size; ind3++) { for (size_t ind4 = 0; ind4 < size; ind4++) { for (size_t ind5 = 0; ind5 < size; ind5++) { - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); tsi_test_frame_protector_config_set_buffer_size( - ssl_fixture->base.config, odd_sizes[ind1], odd_sizes[ind2], - odd_sizes[ind3], odd_sizes[ind4], odd_sizes[ind5]); - tsi_test_do_round_trip(&ssl_fixture->base); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->GetBaseFixture()->config, odd_sizes[ind1], + odd_sizes[ind2], odd_sizes[ind3], odd_sizes[ind4], + odd_sizes[ind5]); + DoRoundTrip(); + DestroyFixture(); } } } @@ -905,24 +961,23 @@ void ssl_tsi_test_do_round_trip_odd_buffer_size() { } } -void ssl_tsi_test_do_handshake_session_cache() { +TEST_P(SslTransportSecurityTest, DoHandshakeSessionCache) { gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_session_cache"); tsi_ssl_session_cache* session_cache = tsi_ssl_session_cache_create_lru(16); char session_ticket_key[kSessionTicketEncryptionKeySize]; - auto do_handshake = [&session_ticket_key, + auto do_handshake = [this, &session_ticket_key, &session_cache](bool session_reused) { - 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("waterzooi.test.google.be"); - ssl_fixture->session_ticket_key = session_ticket_key; - ssl_fixture->session_ticket_key_size = sizeof(session_ticket_key); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetServerNameIndication( + const_cast("waterzooi.test.google.be")); + ssl_fixture_->SetSessionTicketKey(session_ticket_key, + sizeof(session_ticket_key)); tsi_ssl_session_cache_ref(session_cache); - ssl_fixture->session_cache = session_cache; - ssl_fixture->session_reused = session_reused; - tsi_test_do_round_trip(&ssl_fixture->base); - tsi_test_fixture_destroy(fixture); + ssl_fixture_->SetSessionCache(session_cache); + ssl_fixture_->SetSessionReused(session_reused); + DoRoundTrip(); + DestroyFixture(); }; memset(session_ticket_key, 'a', sizeof(session_ticket_key)); do_handshake(false); @@ -937,19 +992,35 @@ void ssl_tsi_test_do_handshake_session_cache() { do_handshake(true); tsi_ssl_session_cache_unref(session_cache); } +#endif // OPENSSL_IS_BORINGSSL -void ssl_tsi_test_do_handshake_with_intermediate_ca() { - gpr_log( - GPR_INFO, - "ssl_tsi_test_do_handshake_with_client_authentication_and_root_store"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); - ssl_fixture->force_client_auth = true; - ssl_fixture->key_cert_lib->use_root_store = true; - ssl_fixture->key_cert_lib->use_cert_signed_by_intermediate_ca = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnServerNoClient) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_server_no_client"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_SERVER_NO_CLIENT); + DoHandshake(); +} + +TEST_P(SslTransportSecurityTest, DoHandshakeAlpnClientServerOk) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_alpn_client_server_ok"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); + ssl_fixture_->SetAlpnMode(ALPN_CLIENT_SERVER_OK); + DoHandshake(); +} + +TEST_P(SslTransportSecurityTest, DoHandshakeWithCustomBioPair) { + gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_custom_bio_pair"); + SetUpSslFixture(/*tls_version=*/std::get<0>(GetParam()), + /*send_client_ca_list=*/std::get<1>(GetParam())); +#if OPENSSL_VERSION_NUMBER >= 0x10100000 + ssl_fixture_->SetBioBufSizes( + /*network_bio_buf_size=*/TSI_TEST_DEFAULT_BUFFER_SIZE, + /*ssl_bio_buf_size=*/256); +#endif + ssl_fixture_->SetForceClientAuth(true); + DoHandshake(); } static const tsi_ssl_handshaker_factory_vtable* original_vtable; @@ -967,7 +1038,7 @@ static void ssl_tsi_test_handshaker_factory_destructor( static tsi_ssl_handshaker_factory_vtable test_handshaker_factory_vtable = { ssl_tsi_test_handshaker_factory_destructor}; -void test_tsi_ssl_client_handshaker_factory_refcounting() { +TEST(SslTransportSecurityTest, TestClientHandshakerFactoryRefcounting) { int i; char* cert_chain = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "client.pem"); @@ -1012,7 +1083,7 @@ void test_tsi_ssl_client_handshaker_factory_refcounting() { gpr_free(cert_chain); } -void test_tsi_ssl_server_handshaker_factory_refcounting() { +TEST(SslTransportSecurityTest, TestServerHandshakerFactoryRefcounting) { int i; tsi_ssl_server_handshaker_factory* server_handshaker_factory; tsi_handshaker* handshaker[3]; @@ -1059,7 +1130,7 @@ void test_tsi_ssl_server_handshaker_factory_refcounting() { // Attempting to create a handshaker factory with invalid parameters should fail // but not crash. -void test_tsi_ssl_client_handshaker_factory_bad_params() { +TEST(SslTransportSecurityTest, TestClientHandshakerFactoryBadParams) { const char* cert_chain = "This is not a valid PEM file."; tsi_ssl_client_handshaker_factory* client_handshaker_factory; @@ -1071,14 +1142,7 @@ void test_tsi_ssl_client_handshaker_factory_bad_params() { tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory); } -void ssl_tsi_test_handshaker_factory_internals() { - gpr_log(GPR_INFO, "ssl_tsi_test_handshaker_factory_internals"); - test_tsi_ssl_client_handshaker_factory_refcounting(); - test_tsi_ssl_server_handshaker_factory_refcounting(); - test_tsi_ssl_client_handshaker_factory_bad_params(); -} - -void ssl_tsi_test_duplicate_root_certificates() { +TEST(SslTransportSecurityTest, DuplicateRootCertificates) { gpr_log(GPR_INFO, "ssl_tsi_test_duplicate_root_certificates"); char* root_cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); char* dup_root_cert = static_cast( @@ -1094,7 +1158,7 @@ void ssl_tsi_test_duplicate_root_certificates() { gpr_free(dup_root_cert); } -void ssl_tsi_test_extract_x509_subject_names() { +TEST(SslTransportSecurityTest, ExtractX509SubjectNames) { gpr_log(GPR_INFO, "ssl_tsi_test_extract_x509_subject_names"); char* cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "multi-domain.pem"); tsi_peer peer; @@ -1198,7 +1262,7 @@ void ssl_tsi_test_extract_x509_subject_names() { tsi_peer_destruct(&peer); } -void ssl_tsi_test_extract_cert_chain() { +TEST(SslTransportSecurityTest, ExtractCertChain) { gpr_log(GPR_INFO, "ssl_tsi_test_extract_cert_chain"); char* cert = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "server1.pem"); char* ca = load_file(SSL_TSI_TEST_CREDENTIALS_DIR "ca.pem"); @@ -1238,74 +1302,6 @@ void ssl_tsi_test_extract_cert_chain() { sk_X509_pop_free(cert_chain, X509_free); } -void ssl_tsi_test_do_handshake_with_custom_bio_pair() { - gpr_log(GPR_INFO, "ssl_tsi_test_do_handshake_with_custom_bio_pair"); - tsi_test_fixture* fixture = ssl_tsi_test_fixture_create(); - ssl_tsi_test_fixture* ssl_fixture = - reinterpret_cast(fixture); -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - ssl_fixture->network_bio_buf_size = TSI_TEST_DEFAULT_BUFFER_SIZE; - ssl_fixture->ssl_bio_buf_size = 256; -#endif - ssl_fixture->force_client_auth = true; - tsi_test_do_handshake(fixture); - tsi_test_fixture_destroy(fixture); -} - -TEST(SslTransportSecurityTest, MainTest) { - grpc_init(); - std::string trust_bundle = GenerateTrustBundle(); - const size_t number_tls_versions = 2; - const tsi_tls_version tls_versions[] = {tsi_tls_version::TSI_TLS1_2, - tsi_tls_version::TSI_TLS1_3}; - for (size_t i = 0; i < number_tls_versions; i++) { - // Set the TLS version to be used in the tests. - test_tls_version = tls_versions[i]; - for (bool send_client_ca_list : {true, false}) { - test_send_client_ca_list = send_client_ca_list; - ssl_tsi_test_do_handshake_tiny_handshake_buffer(); - ssl_tsi_test_do_handshake_small_handshake_buffer(); - ssl_tsi_test_do_handshake(); - ssl_tsi_test_do_handshake_with_root_store(); - ssl_tsi_test_do_handshake_with_large_server_handshake_messages( - trust_bundle); - ssl_tsi_test_do_handshake_with_client_authentication(); - 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_invalid_and_ignored_server_name_indication(); - 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(); -// TODO(gregorycooke) - failing with OpenSSL1.0.2 -#if OPENSSL_VERSION_NUMBER >= 0x10100000 - ssl_tsi_test_do_handshake_skipping_server_certificate_verification(); -#endif // OPENSSL_VERSION_NUMBER >= 0x10100000 - -#ifdef OPENSSL_IS_BORINGSSL - // BoringSSL and OpenSSL have different behaviors on mismatched ALPN. - ssl_tsi_test_do_handshake_alpn_client_no_server(); - ssl_tsi_test_do_handshake_alpn_client_server_mismatch(); - // These tests fail with openssl3 and openssl111 currently but not - // boringssl - ssl_tsi_test_do_handshake_session_cache(); - ssl_tsi_test_do_round_trip_for_all_configs(); - ssl_tsi_test_do_round_trip_with_error_on_stack(); - ssl_tsi_test_do_round_trip_odd_buffer_size(); -#endif - ssl_tsi_test_do_handshake_alpn_server_no_client(); - ssl_tsi_test_do_handshake_alpn_client_server_ok(); - ssl_tsi_test_handshaker_factory_internals(); - ssl_tsi_test_duplicate_root_certificates(); - ssl_tsi_test_extract_x509_subject_names(); - ssl_tsi_test_extract_cert_chain(); - ssl_tsi_test_do_handshake_with_custom_bio_pair(); - ssl_tsi_test_do_handshake_with_intermediate_ca(); - } - } - grpc_shutdown(); -} - int main(int argc, char** argv) { grpc::testing::TestEnvironment env(&argc, argv); ::testing::InitGoogleTest(&argc, argv); diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index 3e01fe662f9..6ada7da27c1 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -529,6 +529,7 @@ grpc_cc_test( srcs = ["client_lb_end2end_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], flaky = True, # TODO(b/151315347) @@ -620,6 +621,7 @@ grpc_cc_test( srcs = ["grpclb_end2end_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], flaky = True, # TODO(b/150567713) diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index e7f406f45e9..97cf1f61555 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -26,6 +26,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -424,7 +425,7 @@ class ClientLbEnd2endTest : public ::testing::Test { absl::Seconds(0.1))) {} void Start(const std::string& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); + LOG(INFO) << "starting server on port " << port_; grpc_core::MutexLock lock(&mu_); started_ = true; thread_ = std::make_unique( @@ -433,7 +434,7 @@ class ClientLbEnd2endTest : public ::testing::Test { cond_.Wait(&mu_); } server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); + LOG(INFO) << "server startup complete"; } void Serve(const std::string& server_host) { @@ -498,10 +499,8 @@ class ClientLbEnd2endTest : public ::testing::Test { absl::Duration timeout = absl::Seconds(30)) { if (stop_index == 0) stop_index = servers_.size(); auto deadline = absl::Now() + (timeout * grpc_test_slowdown_factor()); - gpr_log(GPR_INFO, - "========= WAITING FOR BACKENDS [%" PRIuPTR ", %" PRIuPTR - ") ==========", - start_index, stop_index); + LOG(INFO) << "========= WAITING FOR BACKENDS [" << start_index << ", " + << stop_index << ") =========="; while (!SeenAllServers(start_index, stop_index)) { Status status = SendRpc(stub); if (status_check != nullptr) { @@ -636,17 +635,17 @@ TEST_F(ClientLbEnd2endTest, ChannelIdleness) { // The initial channel state should be IDLE. EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); // After sending RPC, channel state should be READY. - gpr_log(GPR_INFO, "*** SENDING RPC, CHANNEL SHOULD CONNECT ***"); + LOG(INFO) << "*** SENDING RPC, CHANNEL SHOULD CONNECT ***"; response_generator.SetNextResolution(GetServersPorts()); CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); // After a period time not using the channel, the channel state should switch // to IDLE. - gpr_log(GPR_INFO, "*** WAITING FOR CHANNEL TO GO IDLE ***"); + LOG(INFO) << "*** WAITING FOR CHANNEL TO GO IDLE ***"; gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(1200)); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); // Sending a new RPC should awake the IDLE channel. - gpr_log(GPR_INFO, "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***"); + LOG(INFO) << "*** SENDING ANOTHER RPC, CHANNEL SHOULD RECONNECT ***"; response_generator.SetNextResolution(GetServersPorts()); CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); @@ -830,7 +829,7 @@ TEST_F(PickFirstTest, BackOffInitialReconnect) { ASSERT_TRUE(WaitForChannelReady(channel.get())); // Check how long it took. const grpc_core::Duration waited = grpc_core::Timestamp::Now() - t0; - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; // We should have waited at least kInitialBackOffMs. We substract one to // account for test and precision accuracy drift. EXPECT_GE(waited.millis(), @@ -861,7 +860,7 @@ TEST_F(PickFirstTest, BackOffMinReconnect) { const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); const grpc_core::Duration waited = grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; // We should have waited at least kMinReconnectBackOffMs. We substract one to // account for test and precision accuracy drift. EXPECT_GE(waited.millis(), @@ -898,7 +897,7 @@ TEST_F(PickFirstTest, ResetConnectionBackoff) { const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); const grpc_core::Duration waited = grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; // We should have waited less than kInitialBackOffMs. EXPECT_LT(waited.millis(), kInitialBackOffMs * grpc_test_slowdown_factor()); } @@ -919,33 +918,33 @@ TEST_F(ClientLbEnd2endTest, response_generator.SetNextResolution({port}); // Intercept initial connection attempt. auto hold1 = injector.AddHold(port); - gpr_log(GPR_INFO, "=== TRIGGERING INITIAL CONNECTION ATTEMPT"); + LOG(INFO) << "=== TRIGGERING INITIAL CONNECTION ATTEMPT"; EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(/*try_to_connect=*/true)); hold1->Wait(); EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel->GetState(/*try_to_connect=*/false)); // Reset backoff. - gpr_log(GPR_INFO, "=== RESETTING BACKOFF"); + LOG(INFO) << "=== RESETTING BACKOFF"; experimental::ChannelResetConnectionBackoff(channel.get()); // Intercept next attempt. Do this before resuming the first attempt, // just in case the client makes progress faster than this thread. auto hold2 = injector.AddHold(port); // Fail current attempt and wait for next one to start. - gpr_log(GPR_INFO, "=== RESUMING INITIAL ATTEMPT"); + LOG(INFO) << "=== RESUMING INITIAL ATTEMPT"; const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC); hold1->Resume(); - gpr_log(GPR_INFO, "=== WAITING FOR SECOND ATTEMPT"); + LOG(INFO) << "=== WAITING FOR SECOND ATTEMPT"; // This WaitForStateChange() call just makes sure we're doing some polling. EXPECT_TRUE(channel->WaitForStateChange(GRPC_CHANNEL_CONNECTING, grpc_timeout_seconds_to_deadline(1))); hold2->Wait(); const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC); - gpr_log(GPR_INFO, "=== RESUMING SECOND ATTEMPT"); + LOG(INFO) << "=== RESUMING SECOND ATTEMPT"; hold2->Resume(); // Elapsed time should be very short, much less than kInitialBackOffMs. const grpc_core::Duration waited = grpc_core::Duration::FromTimespec(gpr_time_sub(t1, t0)); - gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited.millis()); + VLOG(2) << "Waited " << waited.millis() << " milliseconds"; EXPECT_LT(waited.millis(), 1000 * grpc_test_slowdown_factor()); } @@ -958,21 +957,21 @@ TEST_F(PickFirstTest, Updates) { auto stub = BuildStub(channel); // Perform one RPC against the first server. response_generator.SetNextResolution(GetServersPorts(0, 1)); - gpr_log(GPR_INFO, "****** SET [0] *******"); + LOG(INFO) << "****** SET [0] *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(servers_[0]->service_.request_count(), 1); // An empty update will result in the channel going into TRANSIENT_FAILURE. response_generator.SetNextResolution({}); - gpr_log(GPR_INFO, "****** SET none *******"); + LOG(INFO) << "****** SET none *******"; WaitForChannelNotReady(channel.get()); // Next update introduces servers_[1], making the channel recover. response_generator.SetNextResolution(GetServersPorts(1, 2)); - gpr_log(GPR_INFO, "****** SET [1] *******"); + LOG(INFO) << "****** SET [1] *******"; WaitForChannelReady(channel.get()); WaitForServer(DEBUG_LOCATION, stub, 1); // And again for servers_[2] response_generator.SetNextResolution(GetServersPorts(2, 3)); - gpr_log(GPR_INFO, "****** SET [2] *******"); + LOG(INFO) << "****** SET [2] *******"; WaitForServer(DEBUG_LOCATION, stub, 2); // Check LB policy name for the channel. EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName()); @@ -991,7 +990,7 @@ TEST_F(PickFirstTest, UpdateSuperset) { // Perform one RPC against the first server. ports.emplace_back(servers_[0]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [0] *******"); + LOG(INFO) << "****** SET [0] *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); EXPECT_EQ(servers_[0]->service_.request_count(), 1); servers_[0]->service_.ResetCounters(); @@ -1001,7 +1000,7 @@ TEST_F(PickFirstTest, UpdateSuperset) { ports.emplace_back(servers_[1]->port_); ports.emplace_back(servers_[0]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET superset *******"); + LOG(INFO) << "****** SET superset *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); // We stick to the previously connected server. WaitForServer(DEBUG_LOCATION, stub, 0); @@ -1024,7 +1023,7 @@ TEST_F(PickFirstTest, UpdateToUnconnected) { // Try to send rpcs against a list where the server is available. ports.emplace_back(servers_[0]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [0] *******"); + LOG(INFO) << "****** SET [0] *******"; CheckRpcSendOk(DEBUG_LOCATION, stub); // Send resolution for which all servers are currently unavailable. Eventually @@ -1034,12 +1033,12 @@ TEST_F(PickFirstTest, UpdateToUnconnected) { ports.emplace_back(grpc_pick_unused_port_or_die()); ports.emplace_back(servers_[1]->port_); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** SET [unavailable] *******"); + LOG(INFO) << "****** SET [unavailable] *******"; EXPECT_TRUE(WaitForChannelNotReady(channel.get())); // Ensure that the last resolution was installed correctly by verifying that // the channel becomes ready once one of if its endpoints becomes available. - gpr_log(GPR_INFO, "****** StartServer(1) *******"); + LOG(INFO) << "****** StartServer(1) *******"; StartServer(1); EXPECT_TRUE(WaitForChannelReady(channel.get())); } @@ -1135,21 +1134,21 @@ TEST_F(PickFirstTest, ReresolutionNoSelected) { // The initial resolution only contains dead ports. There won't be any // selected subchannel. Re-resolution will return the same result. response_generator.SetNextResolution(dead_ports); - gpr_log(GPR_INFO, "****** INITIAL RESOLUTION SET *******"); + LOG(INFO) << "****** INITIAL RESOLUTION SET *******"; for (size_t i = 0; i < 10; ++i) { CheckRpcSendFailure( DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE, MakeConnectionFailureRegex("failed to connect to all addresses")); } // PF should request re-resolution. - gpr_log(GPR_INFO, "****** WAITING FOR RE-RESOLUTION *******"); + LOG(INFO) << "****** WAITING FOR RE-RESOLUTION *******"; EXPECT_TRUE(response_generator.Get()->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); - gpr_log(GPR_INFO, "****** RE-RESOLUTION SEEN *******"); + LOG(INFO) << "****** RE-RESOLUTION SEEN *******"; // Send a resolver result that contains reachable ports, so that the // pick_first LB policy can recover soon. response_generator.SetNextResolution(alive_ports); - gpr_log(GPR_INFO, "****** RE-RESOLUTION SENT *******"); + LOG(INFO) << "****** RE-RESOLUTION SENT *******"; WaitForServer(DEBUG_LOCATION, stub, 0, [](const Status& status) { EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); EXPECT_THAT(status.error_message(), @@ -1169,12 +1168,12 @@ TEST_F(PickFirstTest, ReconnectWithoutNewResolverResult) { auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); + LOG(INFO) << "****** INITIAL CONNECTION *******"; WaitForServer(DEBUG_LOCATION, stub, 0); - gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); + LOG(INFO) << "****** STOPPING SERVER ******"; servers_[0]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - gpr_log(GPR_INFO, "****** RESTARTING SERVER ******"); + LOG(INFO) << "****** RESTARTING SERVER ******"; StartServers(1, ports); WaitForServer(DEBUG_LOCATION, stub, 0); } @@ -1188,12 +1187,12 @@ TEST_F(PickFirstTest, ReconnectWithoutNewResolverResultStartsFromTopOfList) { auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** INITIAL CONNECTION *******"); + LOG(INFO) << "****** INITIAL CONNECTION *******"; WaitForServer(DEBUG_LOCATION, stub, 1); - gpr_log(GPR_INFO, "****** STOPPING SERVER ******"); + LOG(INFO) << "****** STOPPING SERVER ******"; servers_[1]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - gpr_log(GPR_INFO, "****** STARTING BOTH SERVERS ******"); + LOG(INFO) << "****** STARTING BOTH SERVERS ******"; StartServers(2, ports); WaitForServer(DEBUG_LOCATION, stub, 0); } @@ -1202,21 +1201,21 @@ TEST_F(PickFirstTest, FailsEmptyResolverUpdate) { FakeResolverResponseGeneratorWrapper response_generator; auto channel = BuildChannel("pick_first", response_generator); auto stub = BuildStub(channel); - gpr_log(GPR_INFO, "****** SENDING INITIAL RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING INITIAL RESOLVER RESULT *******"; // Send a resolver result with an empty address list and a callback // that triggers a notification. grpc_core::Notification notification; grpc_core::Resolver::Result result; result.addresses.emplace(); result.result_health_callback = [&](absl::Status status) { - gpr_log(GPR_INFO, "****** RESULT HEALTH CALLBACK *******"); + LOG(INFO) << "****** RESULT HEALTH CALLBACK *******"; EXPECT_EQ(absl::StatusCode::kUnavailable, status.code()); EXPECT_EQ("address list must not be empty", status.message()) << status; notification.Notify(); }; response_generator.SetResponse(std::move(result)); // Wait for channel to report TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "****** TELLING CHANNEL TO CONNECT *******"); + LOG(INFO) << "****** TELLING CHANNEL TO CONNECT *******"; auto predicate = [](grpc_connectivity_state state) { return state == GRPC_CHANNEL_TRANSIENT_FAILURE; }; @@ -1225,10 +1224,10 @@ TEST_F(PickFirstTest, FailsEmptyResolverUpdate) { // Callback should run. notification.WaitForNotification(); // Return a valid address. - gpr_log(GPR_INFO, "****** SENDING NEXT RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING NEXT RESOLVER RESULT *******"; StartServers(1); response_generator.SetNextResolution(GetServersPorts()); - gpr_log(GPR_INFO, "****** SENDING WAIT_FOR_READY RPC *******"); + LOG(INFO) << "****** SENDING WAIT_FOR_READY RPC *******"; CheckRpcSendOk(DEBUG_LOCATION, stub, /*wait_for_ready=*/true); } @@ -1239,22 +1238,22 @@ TEST_F(PickFirstTest, CheckStateBeforeStartWatch) { auto channel_1 = BuildChannel("pick_first", response_generator); auto stub_1 = BuildStub(channel_1); response_generator.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 1 *******"); + LOG(INFO) << "****** RESOLUTION SET FOR CHANNEL 1 *******"; WaitForServer(DEBUG_LOCATION, stub_1, 0); - gpr_log(GPR_INFO, "****** CHANNEL 1 CONNECTED *******"); + LOG(INFO) << "****** CHANNEL 1 CONNECTED *******"; servers_[0]->Shutdown(); EXPECT_TRUE(WaitForChannelNotReady(channel_1.get())); // Channel 1 will receive a re-resolution containing the same server. It will // create a new subchannel and hold a ref to it. StartServers(1, ports); - gpr_log(GPR_INFO, "****** SERVER RESTARTED *******"); + LOG(INFO) << "****** SERVER RESTARTED *******"; FakeResolverResponseGeneratorWrapper response_generator_2; auto channel_2 = BuildChannel("pick_first", response_generator_2); auto stub_2 = BuildStub(channel_2); response_generator_2.SetNextResolution(ports); - gpr_log(GPR_INFO, "****** RESOLUTION SET FOR CHANNEL 2 *******"); + LOG(INFO) << "****** RESOLUTION SET FOR CHANNEL 2 *******"; WaitForServer(DEBUG_LOCATION, stub_2, 0); - gpr_log(GPR_INFO, "****** CHANNEL 2 CONNECTED *******"); + LOG(INFO) << "****** CHANNEL 2 CONNECTED *******"; servers_[0]->Shutdown(); // Wait until the disconnection has triggered the connectivity notification. // Otherwise, the subchannel may be picked for next call but will fail soon. @@ -1262,11 +1261,11 @@ TEST_F(PickFirstTest, CheckStateBeforeStartWatch) { // Channel 2 will also receive a re-resolution containing the same server. // Both channels will ref the same subchannel that failed. StartServers(1, ports); - gpr_log(GPR_INFO, "****** SERVER RESTARTED AGAIN *******"); - gpr_log(GPR_INFO, "****** CHANNEL 2 STARTING A CALL *******"); + LOG(INFO) << "****** SERVER RESTARTED AGAIN *******"; + LOG(INFO) << "****** CHANNEL 2 STARTING A CALL *******"; // The first call after the server restart will succeed. CheckRpcSendOk(DEBUG_LOCATION, stub_2); - gpr_log(GPR_INFO, "****** CHANNEL 2 FINISHED A CALL *******"); + LOG(INFO) << "****** CHANNEL 2 FINISHED A CALL *******"; // Check LB policy name for the channel. EXPECT_EQ("pick_first", channel_1->GetLoadBalancingPolicyName()); // Check LB policy name for the channel. @@ -1411,7 +1410,7 @@ TEST_F(RoundRobinTest, Updates) { auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); // Start with a single server. - gpr_log(GPR_INFO, "*** FIRST BACKEND ***"); + LOG(INFO) << "*** FIRST BACKEND ***"; std::vector ports = {servers_[0]->port_}; response_generator.SetNextResolution(ports); WaitForServer(DEBUG_LOCATION, stub, 0); @@ -1422,7 +1421,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(0, servers_[2]->service_.request_count()); ResetCounters(); // And now for the second server. - gpr_log(GPR_INFO, "*** SECOND BACKEND ***"); + LOG(INFO) << "*** SECOND BACKEND ***"; ports.clear(); ports.emplace_back(servers_[1]->port_); response_generator.SetNextResolution(ports); @@ -1436,7 +1435,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(0, servers_[2]->service_.request_count()); ResetCounters(); // ... and for the last server. - gpr_log(GPR_INFO, "*** THIRD BACKEND ***"); + LOG(INFO) << "*** THIRD BACKEND ***"; ports.clear(); ports.emplace_back(servers_[2]->port_); response_generator.SetNextResolution(ports); @@ -1447,7 +1446,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(10, servers_[2]->service_.request_count()); ResetCounters(); // Back to all servers. - gpr_log(GPR_INFO, "*** ALL BACKENDS ***"); + LOG(INFO) << "*** ALL BACKENDS ***"; ports.clear(); ports.emplace_back(servers_[0]->port_); ports.emplace_back(servers_[1]->port_); @@ -1461,7 +1460,7 @@ TEST_F(RoundRobinTest, Updates) { EXPECT_EQ(1, servers_[2]->service_.request_count()); ResetCounters(); // An empty update will result in the channel going into TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "*** NO BACKENDS ***"); + LOG(INFO) << "*** NO BACKENDS ***"; ports.clear(); response_generator.SetNextResolution(ports); WaitForChannelNotReady(channel.get()); @@ -1469,7 +1468,7 @@ TEST_F(RoundRobinTest, Updates) { "empty address list: fake resolver empty address list"); servers_[0]->service_.ResetCounters(); // Next update introduces servers_[1], making the channel recover. - gpr_log(GPR_INFO, "*** BACK TO SECOND BACKEND ***"); + LOG(INFO) << "*** BACK TO SECOND BACKEND ***"; ports.clear(); ports.emplace_back(servers_[1]->port_); response_generator.SetNextResolution(ports); @@ -1550,15 +1549,15 @@ TEST_F(RoundRobinTest, ReresolveOnSubchannelConnectionFailure) { // Wait for both servers to be seen. WaitForServers(DEBUG_LOCATION, stub, 0, 2); // Have server 0 send a GOAWAY. This should trigger a re-resolution. - gpr_log(GPR_INFO, "****** SENDING GOAWAY FROM SERVER 0 *******"); + LOG(INFO) << "****** SENDING GOAWAY FROM SERVER 0 *******"; { grpc_core::ExecCtx exec_ctx; grpc_core::Server::FromC(servers_[0]->server_->c_server())->SendGoaways(); } - gpr_log(GPR_INFO, "****** WAITING FOR RE-RESOLUTION REQUEST *******"); + LOG(INFO) << "****** WAITING FOR RE-RESOLUTION REQUEST *******"; EXPECT_TRUE(response_generator.Get()->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); - gpr_log(GPR_INFO, "****** RE-RESOLUTION REQUEST SEEN *******"); + LOG(INFO) << "****** RE-RESOLUTION REQUEST SEEN *******"; // Tell the fake resolver to send an update that adds the last server, but // only when the LB policy requests re-resolution. ports.push_back(servers_[2]->port_); @@ -1571,7 +1570,7 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) { FakeResolverResponseGeneratorWrapper response_generator; auto channel = BuildChannel("round_robin", response_generator); auto stub = BuildStub(channel); - gpr_log(GPR_INFO, "****** SENDING INITIAL RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING INITIAL RESOLVER RESULT *******"; // Send a resolver result with an empty address list and a callback // that triggers a notification. grpc_core::Notification notification; @@ -1585,7 +1584,7 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) { }; response_generator.SetResponse(std::move(result)); // Wait for channel to report TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "****** TELLING CHANNEL TO CONNECT *******"); + LOG(INFO) << "****** TELLING CHANNEL TO CONNECT *******"; auto predicate = [](grpc_connectivity_state state) { return state == GRPC_CHANNEL_TRANSIENT_FAILURE; }; @@ -1594,10 +1593,10 @@ TEST_F(RoundRobinTest, FailsEmptyResolverUpdate) { // Callback should have been run. notification.WaitForNotification(); // Return a valid address. - gpr_log(GPR_INFO, "****** SENDING NEXT RESOLVER RESULT *******"); + LOG(INFO) << "****** SENDING NEXT RESOLVER RESULT *******"; StartServers(1); response_generator.SetNextResolution(GetServersPorts()); - gpr_log(GPR_INFO, "****** SENDING WAIT_FOR_READY RPC *******"); + LOG(INFO) << "****** SENDING WAIT_FOR_READY RPC *******"; CheckRpcSendOk(DEBUG_LOCATION, stub, /*wait_for_ready=*/true); } @@ -1658,7 +1657,7 @@ TEST_F(RoundRobinTest, StaysInTransientFailureInSubsequentConnecting) { response_generator.SetNextResolution({port}); // Allow first connection attempt to fail normally, and wait for // channel to report TRANSIENT_FAILURE. - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO REPORT TF ==="); + LOG(INFO) << "=== WAITING FOR CHANNEL TO REPORT TF ==="; auto predicate = [](grpc_connectivity_state state) { return state == GRPC_CHANNEL_TRANSIENT_FAILURE; }; @@ -1673,7 +1672,7 @@ TEST_F(RoundRobinTest, StaysInTransientFailureInSubsequentConnecting) { EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel->GetState(false)); // Send a few RPCs, just to give the channel a chance to propagate a // new picker, in case it was going to incorrectly do so. - gpr_log(GPR_INFO, "=== EXPECTING RPCs TO FAIL ==="); + LOG(INFO) << "=== EXPECTING RPCs TO FAIL ==="; for (size_t i = 0; i < 5; ++i) { CheckRpcSendFailure( DEBUG_LOCATION, stub, StatusCode::UNAVAILABLE, @@ -1718,7 +1717,7 @@ TEST_F(RoundRobinTest, ReportsLatestStatusInTransientFailure) { "Survey says... Bzzzzt!"))(status.error_message())) { break; } - gpr_log(GPR_INFO, "STATUS MESSAGE: %s", status.error_message().c_str()); + LOG(INFO) << "STATUS MESSAGE: " << status.error_message(); EXPECT_THAT(status.error_message(), ::testing::MatchesRegex(MakeConnectionFailureRegex( "connections to all backends failing"))); @@ -1740,21 +1739,21 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) { auto stub = BuildStub(channel); response_generator.SetNextResolution(GetServersPorts()); // Start a thread constantly sending RPCs in a loop. - gpr_log(GPR_INFO, "=== STARTING CLIENT THREAD ==="); + LOG(INFO) << "=== STARTING CLIENT THREAD ==="; std::atomic shutdown{false}; gpr_event ev; gpr_event_init(&ev); std::thread thd([&]() { - gpr_log(GPR_INFO, "sending first RPC"); + LOG(INFO) << "sending first RPC"; CheckRpcSendOk(DEBUG_LOCATION, stub); gpr_event_set(&ev, reinterpret_cast(1)); while (!shutdown.load()) { - gpr_log(GPR_INFO, "sending RPC"); + LOG(INFO) << "sending RPC"; CheckRpcSendOk(DEBUG_LOCATION, stub); } }); // Wait for first RPC to complete. - gpr_log(GPR_INFO, "=== WAITING FOR FIRST RPC TO COMPLETE ==="); + LOG(INFO) << "=== WAITING FOR FIRST RPC TO COMPLETE ==="; ASSERT_EQ(reinterpret_cast(1), gpr_event_wait(&ev, grpc_timeout_seconds_to_deadline(1))); // Channel should now be READY. @@ -1765,7 +1764,7 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) { // Now kill the server. The subchannel should report IDLE and be // immediately reconnected to, but this should not cause any test // failures. - gpr_log(GPR_INFO, "=== SHUTTING DOWN SERVER ==="); + LOG(INFO) << "=== SHUTTING DOWN SERVER ==="; { grpc_core::ExecCtx exec_ctx; grpc_core::Server::FromC(servers_[0]->server_->c_server())->SendGoaways(); @@ -1773,17 +1772,17 @@ TEST_F(RoundRobinTest, DoesNotFailRpcsUponDisconnection) { gpr_sleep_until(grpc_timeout_seconds_to_deadline(1)); servers_[0]->Shutdown(); // Wait for next attempt to start. - gpr_log(GPR_INFO, "=== WAITING FOR RECONNECTION ATTEMPT ==="); + LOG(INFO) << "=== WAITING FOR RECONNECTION ATTEMPT ==="; hold1->Wait(); // Start server and allow attempt to continue. - gpr_log(GPR_INFO, "=== RESTARTING SERVER ==="); + LOG(INFO) << "=== RESTARTING SERVER ==="; StartServer(0); hold1->Resume(); // Wait for next attempt to complete. - gpr_log(GPR_INFO, "=== WAITING FOR RECONNECTION ATTEMPT TO COMPLETE ==="); + LOG(INFO) << "=== WAITING FOR RECONNECTION ATTEMPT TO COMPLETE ==="; hold1->WaitForCompletion(); // Now shut down the thread. - gpr_log(GPR_INFO, "=== SHUTTING DOWN CLIENT THREAD ==="); + LOG(INFO) << "=== SHUTTING DOWN CLIENT THREAD ==="; shutdown.store(true); thd.join(); } @@ -1871,14 +1870,13 @@ TEST_F(RoundRobinTest, HealthChecking) { auto stub = BuildStub(channel); response_generator.SetNextResolution(GetServersPorts()); // Channel should not become READY, because health checks should be failing. - gpr_log(GPR_INFO, - "*** initial state: unknown health check service name for " - "all servers"); + LOG(INFO) + << "*** initial state: unknown health check service name for all servers"; EXPECT_FALSE(WaitForChannelReady(channel.get(), 1)); // Now set one of the servers to be healthy. // The channel should become healthy and all requests should go to // the healthy server. - gpr_log(GPR_INFO, "*** server 0 healthy"); + LOG(INFO) << "*** server 0 healthy"; servers_[0]->SetServingStatus("health_check_service_name", true); EXPECT_TRUE(WaitForChannelReady(channel.get())); // New channel state may be reported before the picker is updated, so @@ -1891,7 +1889,7 @@ TEST_F(RoundRobinTest, HealthChecking) { EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(0, servers_[2]->service_.request_count()); // Now set a second server to be healthy. - gpr_log(GPR_INFO, "*** server 2 healthy"); + LOG(INFO) << "*** server 2 healthy"; servers_[2]->SetServingStatus("health_check_service_name", true); WaitForServer(DEBUG_LOCATION, stub, 2); for (int i = 0; i < 10; ++i) { @@ -1901,7 +1899,7 @@ TEST_F(RoundRobinTest, HealthChecking) { EXPECT_EQ(0, servers_[1]->service_.request_count()); EXPECT_EQ(5, servers_[2]->service_.request_count()); // Now set the remaining server to be healthy. - gpr_log(GPR_INFO, "*** server 1 healthy"); + LOG(INFO) << "*** server 1 healthy"; servers_[1]->SetServingStatus("health_check_service_name", true); WaitForServer(DEBUG_LOCATION, stub, 1); for (int i = 0; i < 9; ++i) { @@ -1914,7 +1912,7 @@ TEST_F(RoundRobinTest, HealthChecking) { // unhealthiness has hit the client. We know that the client will see // this when we send kNumServers requests and one of the remaining servers // sees two of the requests. - gpr_log(GPR_INFO, "*** server 0 unhealthy"); + LOG(INFO) << "*** server 0 unhealthy"; servers_[0]->SetServingStatus("health_check_service_name", false); do { ResetCounters(); @@ -1925,7 +1923,7 @@ TEST_F(RoundRobinTest, HealthChecking) { servers_[2]->service_.request_count() != 2); // Now set the remaining two servers to be unhealthy. Make sure the // channel leaves READY state and that RPCs fail. - gpr_log(GPR_INFO, "*** all servers unhealthy"); + LOG(INFO) << "*** all servers unhealthy"; servers_[1]->SetServingStatus("health_check_service_name", false); servers_[2]->SetServingStatus("health_check_service_name", false); EXPECT_TRUE(WaitForChannelNotReady(channel.get())); diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc index fa3f9936a99..ef1cfc1382d 100644 --- a/test/cpp/end2end/grpclb_end2end_test.cc +++ b/test/cpp/end2end/grpclb_end2end_test.cc @@ -27,6 +27,7 @@ #include "absl/cleanup/cleanup.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -225,7 +226,7 @@ class BalancerServiceImpl : public BalancerService { shutdown_ = true; } ShutdownStream(); - gpr_log(GPR_INFO, "LB[%p]: shut down", this); + LOG(INFO) << "LB[" << this << "]: shut down"; } void set_client_load_reporting_interval_seconds(int seconds) { @@ -285,11 +286,11 @@ class BalancerServiceImpl : public BalancerService { private: // Request handler. Status BalanceLoad(ServerContext* context, Stream* stream) override { - gpr_log(GPR_INFO, "LB[%p]: BalanceLoad", this); + LOG(INFO) << "LB[" << this << "]: BalanceLoad"; { grpc_core::MutexLock lock(&mu_); if (shutdown_) { - gpr_log(GPR_INFO, "LB[%p]: shutdown at stream start", this); + LOG(INFO) << "LB[" << this << "]: shutdown at stream start"; return Status::OK; } } @@ -310,7 +311,7 @@ class BalancerServiceImpl : public BalancerService { // Read initial request. LoadBalanceRequest request; if (!stream->Read(&request)) { - gpr_log(GPR_INFO, "LB[%p]: stream read returned false", this); + LOG(INFO) << "LB[" << this << "]: stream read returned false"; return Status::OK; } EXPECT_TRUE(request.has_initial_request()); @@ -319,8 +320,8 @@ class BalancerServiceImpl : public BalancerService { service_names_.push_back(request.initial_request().name()); } IncreaseRequestCount(); - gpr_log(GPR_INFO, "LB[%p]: received initial message '%s'", this, - request.DebugString().c_str()); + LOG(INFO) << "LB[" << this << "]: received initial message '" + << request.DebugString() << "'"; // Send initial response. LoadBalanceResponse response; auto* initial_response = response.mutable_initial_response(); @@ -334,11 +335,11 @@ class BalancerServiceImpl : public BalancerService { std::thread reader(std::bind(&BalancerServiceImpl::ReadThread, this, stream, &reader_shutdown)); auto thread_cleanup = absl::MakeCleanup([&]() { - gpr_log(GPR_INFO, "shutting down reader thread"); + LOG(INFO) << "shutting down reader thread"; reader_shutdown.Notify(); - gpr_log(GPR_INFO, "joining reader thread"); + LOG(INFO) << "joining reader thread"; reader.join(); - gpr_log(GPR_INFO, "joining reader thread complete"); + LOG(INFO) << "joining reader thread complete"; }); // Send responses as instructed by the test. while (true) { @@ -347,12 +348,12 @@ class BalancerServiceImpl : public BalancerService { context->TryCancel(); break; } - gpr_log(GPR_INFO, "LB[%p]: Sending response: %s", this, - response->DebugString().c_str()); + LOG(INFO) << "LB[" << this + << "]: Sending response: " << response->DebugString(); IncreaseResponseCount(); stream->Write(*response); } - gpr_log(GPR_INFO, "LB[%p]: done", this); + LOG(INFO) << "LB[" << this << "]: done"; return Status::OK; } @@ -360,8 +361,8 @@ class BalancerServiceImpl : public BalancerService { void ReadThread(Stream* stream, absl::Notification* shutdown) { LoadBalanceRequest request; while (!shutdown->HasBeenNotified() && stream->Read(&request)) { - gpr_log(GPR_INFO, "LB[%p]: received client load report message '%s'", - this, request.DebugString().c_str()); + LOG(INFO) << "LB[" << this << "]: received client load report message '" + << request.DebugString() << "'"; EXPECT_GT(client_load_reporting_interval_seconds_, 0); EXPECT_TRUE(request.has_client_stats()); ClientStats load_report; @@ -451,7 +452,7 @@ class GrpclbEnd2endTest : public ::testing::Test { ~ServerThread() { Shutdown(); } void Start() { - gpr_log(GPR_INFO, "starting %s server on port %d", type_.c_str(), port_); + LOG(INFO) << "starting " << type_ << " server on port " << port_; CHECK(!running_); running_ = true; service_.Start(); @@ -463,7 +464,7 @@ class GrpclbEnd2endTest : public ::testing::Test { thread_ = std::make_unique( std::bind(&ServerThread::Serve, this, &mu, &cond)); cond.Wait(&mu); - gpr_log(GPR_INFO, "%s server startup complete", type_.c_str()); + LOG(INFO) << type_ << " server startup complete"; } void Serve(grpc_core::Mutex* mu, grpc_core::CondVar* cond) { @@ -481,11 +482,11 @@ class GrpclbEnd2endTest : public ::testing::Test { void Shutdown() { if (!running_) return; - gpr_log(GPR_INFO, "%s about to shutdown", type_.c_str()); + LOG(INFO) << type_ << " about to shutdown"; service_.Shutdown(); server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); thread_->join(); - gpr_log(GPR_INFO, "%s shutdown completed", type_.c_str()); + LOG(INFO) << type_ << " shutdown completed"; running_ = false; } @@ -667,8 +668,8 @@ class GrpclbEnd2endTest : public ::testing::Test { size_t start_index = 0, size_t stop_index = 0, WaitForBackendOptions options = WaitForBackendOptions(), SourceLocation location = SourceLocation()) { - gpr_log(GPR_INFO, "Waiting for backends [%" PRIuPTR ", %" PRIuPTR ")", - start_index, stop_index); + LOG(INFO) << "Waiting for backends [" << start_index << ", " << stop_index + << ")"; const absl::Time deadline = absl::Now() + absl::Seconds(options.timeout_seconds * grpc_test_slowdown_factor()); @@ -689,11 +690,11 @@ class GrpclbEnd2endTest : public ::testing::Test { SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops); } ResetBackendCounters(); - gpr_log(GPR_INFO, - "Performed %d warm up requests (a multiple of %d) against the " - "backends. %d succeeded, %d failed, %d dropped.", - num_total, options.num_requests_multiple_of, num_ok, num_failure, - num_drops); + LOG(INFO) << "Performed " << num_total + << " warm up requests (a multiple of " + << options.num_requests_multiple_of << ") against the backends. " + << num_ok << " succeeded, " << num_failure << " failed, " + << num_drops << " dropped."; return std::make_tuple(num_ok, num_failure, num_drops); } @@ -1299,9 +1300,9 @@ TEST_F(GrpclbEnd2endTest, SetNextResolutionDefaultBalancer(); WaitForBackend(0); // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); @@ -1314,9 +1315,9 @@ TEST_F(GrpclbEnd2endTest, // Now tell the channel to use balancer 2. However, the stream to the // default balancer is not terminated, so the client will continue to // use it. - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + LOG(INFO) << "========= ABOUT TO UPDATE 1 =========="; SetNextResolution({balancer2->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + LOG(INFO) << "========= UPDATE 1 DONE =========="; // Now the default balancer sends backend 2. SendBalancerResponse(BuildResponseForBackends({backends_[2]->port()}, {})); WaitForBackend(2); @@ -1339,9 +1340,9 @@ TEST_F(GrpclbEnd2endTest, // Wait until the first backend is ready. WaitForBackend(0); // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); @@ -1351,15 +1352,15 @@ TEST_F(GrpclbEnd2endTest, EXPECT_EQ(0U, balancer2->service().request_count()); EXPECT_EQ(0U, balancer2->service().response_count()); // Send another address list with the same list of balancers. - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + LOG(INFO) << "========= ABOUT TO UPDATE 1 =========="; SetNextResolution({balancer_->port(), balancer2->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + LOG(INFO) << "========= UPDATE 1 DONE =========="; // Shut down the balancer stream to force the client to create a new one. // The new stream should go to the default balancer, since the // underlying connection should not have been broken. - gpr_log(GPR_INFO, "========= SHUTTING DOWN BALANCER CALL =========="); + LOG(INFO) << "========= SHUTTING DOWN BALANCER CALL =========="; balancer_->service().ShutdownStream(); - gpr_log(GPR_INFO, "========= DONE SHUTTING DOWN BALANCER CALL =========="); + LOG(INFO) << "========= DONE SHUTTING DOWN BALANCER CALL =========="; // Wait until client has created a new balancer stream. EXPECT_TRUE(balancer_->service().WaitForNewStream(1)); // Make sure there was only one client connection seen by the balancer. @@ -1383,34 +1384,34 @@ TEST_F(GrpclbEnd2endTest, BalancerDiesThenSwitchToNewBalancer) { EXPECT_EQ(0U, balancer2->service().request_count()); EXPECT_EQ(0U, balancer2->service().response_count()); // Send 10 RPCs. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); // Kill default balancer. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER *************"); + LOG(INFO) << "********** ABOUT TO KILL BALANCER *************"; balancer_->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BALANCER *************"); + LOG(INFO) << "********** KILLED BALANCER *************"; // Channel should continue using the last backend it saw from the // balancer before the balancer died. - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + LOG(INFO) << "========= BEFORE SECOND BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + LOG(INFO) << "========= DONE WITH SECOND BATCH =========="; // All 10 requests should again have gone to the first backend. EXPECT_EQ(20U, backends_[0]->service().request_count()); EXPECT_EQ(0U, backends_[1]->service().request_count()); // Tell channel to start using balancer 2. - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + LOG(INFO) << "========= ABOUT TO UPDATE 1 =========="; SetNextResolution({balancer2->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + LOG(INFO) << "========= UPDATE 1 DONE =========="; // Channel should start using backend 1. WaitForBackend(1); // This is serviced by the updated RR policy - gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + LOG(INFO) << "========= BEFORE THIRD BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + LOG(INFO) << "========= DONE WITH THIRD BATCH =========="; // All 10 requests should have gone to the second backend. EXPECT_EQ(0U, backends_[0]->service().request_count()); EXPECT_EQ(10U, backends_[1]->service().request_count()); @@ -1428,15 +1429,15 @@ TEST_F(GrpclbEnd2endTest, ReresolveDeadBackendWhileInFallback) { // responds, and a fallback backend. SetNextResolution({balancer_->port()}, {backends_[0]->port()}); // Start servers and send 10 RPCs per server. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the fallback backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); // Kill backend 0. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BACKEND 0 *************"); + LOG(INFO) << "********** ABOUT TO KILL BACKEND 0 *************"; backends_[0]->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BACKEND 0 *************"); + LOG(INFO) << "********** KILLED BACKEND 0 *************"; // This should trigger re-resolution. EXPECT_TRUE(response_generator_->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); @@ -1446,9 +1447,9 @@ TEST_F(GrpclbEnd2endTest, ReresolveDeadBackendWhileInFallback) { // Wait until re-resolution has been seen, as signaled by the second backend // receiving a request. WaitForBackend(1); - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + LOG(INFO) << "========= BEFORE SECOND BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + LOG(INFO) << "========= DONE WITH SECOND BATCH =========="; // All 10 requests should have gone to the second backend. EXPECT_EQ(10U, backends_[1]->service().request_count()); EXPECT_EQ(1U, balancer_->service().request_count()); @@ -1467,9 +1468,9 @@ TEST_F(GrpclbEnd2endTest, ReresolveWhenBalancerCallFails) { SetNextResolutionDefaultBalancer(); WaitForBackend(0); // Send 10 RPCs. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + LOG(INFO) << "========= BEFORE FIRST BATCH =========="; CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + LOG(INFO) << "========= DONE WITH FIRST BATCH =========="; // All 10 requests should have gone to the first backend. EXPECT_EQ(10U, backends_[0]->service().request_count()); // Balancer 0 got a single request and sent a single request. @@ -1478,13 +1479,13 @@ TEST_F(GrpclbEnd2endTest, ReresolveWhenBalancerCallFails) { EXPECT_EQ(0U, balancer2->service().request_count()); EXPECT_EQ(0U, balancer2->service().response_count()); // Kill balancer 0. - gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); + LOG(INFO) << "********** ABOUT TO KILL BALANCER 0 *************"; balancer_->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); + LOG(INFO) << "********** KILLED BALANCER 0 *************"; // This should trigger a re-resolution. EXPECT_TRUE(response_generator_->WaitForReresolutionRequest( absl::Seconds(5 * grpc_test_slowdown_factor()))); - gpr_log(GPR_INFO, "********** SAW RE-RESOLUTION REQUEST *************"); + LOG(INFO) << "********** SAW RE-RESOLUTION REQUEST *************"; // Re-resolution result switches to balancer 2. SetNextResolution({balancer2->port()}); // Client should start using backend 1. diff --git a/test/cpp/end2end/rls_end2end_test.cc b/test/cpp/end2end/rls_end2end_test.cc index 189c4c2d34c..ca6616fe6b7 100644 --- a/test/cpp/end2end/rls_end2end_test.cc +++ b/test/cpp/end2end/rls_end2end_test.cc @@ -1535,24 +1535,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) { EXPECT_EQ(backends_[1]->service_.request_count(), 0); // Check exported metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target0, "complete"}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target1, "complete"}, {}), absl::nullopt); - EXPECT_EQ(stats_plugin_->GetCounterValue( + EXPECT_EQ(stats_plugin_->GetUInt64CounterValue( kMetricFailedPicks, {target_uri_, rls_server_target_}, {}), absl::nullopt); stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheEntries, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}), ::testing::Optional(1)); - auto cache_size = stats_plugin_->GetCallbackGaugeValue( + auto cache_size = stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}); EXPECT_THAT(cache_size, ::testing::Optional(::testing::Ge(1))); @@ -1567,24 +1567,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) { EXPECT_EQ(backends_[1]->service_.request_count(), 1); // Check exported metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target0, "complete"}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target1, "complete"}, {}), ::testing::Optional(1)); - EXPECT_EQ(stats_plugin_->GetCounterValue( + EXPECT_EQ(stats_plugin_->GetUInt64CounterValue( kMetricFailedPicks, {target_uri_, rls_server_target_}, {}), absl::nullopt); stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheEntries, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}), ::testing::Optional(2)); - auto cache_size2 = stats_plugin_->GetCallbackGaugeValue( + auto cache_size2 = stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}); EXPECT_THAT(cache_size2, ::testing::Optional(::testing::Ge(2))); @@ -1611,24 +1611,24 @@ TEST_F(RlsMetricsEnd2endTest, MetricValues) { EXPECT_EQ(backends_[1]->service_.request_count(), 1); // Check exported metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target0, "complete"}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricTargetPicks, {target_uri_, rls_server_target_, rls_target1, "complete"}, {}), ::testing::Optional(1)); - EXPECT_THAT(stats_plugin_->GetCounterValue( + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue( kMetricFailedPicks, {target_uri_, rls_server_target_}, {}), ::testing::Optional(1)); stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheEntries, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}), ::testing::Optional(3)); - auto cache_size3 = stats_plugin_->GetCallbackGaugeValue( + auto cache_size3 = stats_plugin_->GetInt64CallbackGaugeValue( kMetricCacheSize, {target_uri_, rls_server_target_, kRlsInstanceUuid}, {}); EXPECT_THAT(cache_size3, ::testing::Optional(::testing::Ge(3))); @@ -1678,7 +1678,7 @@ TEST_F(RlsMetricsEnd2endTest, MetricValuesDefaultTargetRpcs) { EXPECT_EQ(backends_[0]->service_.request_count(), 1); // Check expected metrics. EXPECT_THAT( - stats_plugin_->GetCounterValue( + stats_plugin_->GetUInt64CounterValue( kMetricDefaultTargetPicks, {target_uri_, rls_server_target_, default_target, "complete"}, {}), ::testing::Optional(1)); diff --git a/test/cpp/end2end/xds/BUILD b/test/cpp/end2end/xds/BUILD index 5dd690f6a7b..15afd38eb26 100644 --- a/test/cpp/end2end/xds/BUILD +++ b/test/cpp/end2end/xds/BUILD @@ -25,7 +25,10 @@ grpc_cc_library( name = "xds_server", srcs = ["xds_server.cc"], hdrs = ["xds_server.h"], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], visibility = ["@grpc:xds_end2end_test_utils"], deps = [ "//:gpr", @@ -349,6 +352,7 @@ grpc_cc_test( srcs = ["xds_ring_hash_end2end_test.cc"], external_deps = [ "absl/log:check", + "absl/log:log", "gtest", ], flaky = True, # TODO(b/144705388) diff --git a/test/cpp/end2end/xds/xds_core_end2end_test.cc b/test/cpp/end2end/xds/xds_core_end2end_test.cc index fd9cc6cac2d..ebc97f4a8e8 100644 --- a/test/cpp/end2end/xds/xds_core_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_core_end2end_test.cc @@ -1217,11 +1217,11 @@ TEST_P(XdsMetricsTest, MetricValues) { CheckRpcSendOk(DEBUG_LOCATION); stats_plugin_->TriggerCallbacks(); // Check client metrics. - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected, - {kTarget, kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( + kMetricConnected, {kTarget, kXdsServer}, {}), ::testing::Optional(1)); - EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure, - {kTarget, kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure, + {kTarget, kXdsServer}, {}), absl::nullopt); for (absl::string_view type_url : {"envoy.config.listener.v3.Listener", @@ -1229,37 +1229,37 @@ TEST_P(XdsMetricsTest, MetricValues) { "envoy.config.cluster.v3.Cluster", "envoy.config.endpoint.v3.ClusterLoadAssignment"}) { EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid, - {kTarget, kXdsServer, type_url}, {}), + stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesValid, {kTarget, kXdsServer, type_url}, {}), ::testing::Optional(1)); EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid, - {kTarget, kXdsServer, type_url}, {}), + stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesInvalid, {kTarget, kXdsServer, type_url}, {}), ::testing::Optional(0)); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue( + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( kMetricResources, {kTarget, "#old", type_url, "acked"}, {}), ::testing::Optional(1)); } // Check server metrics. - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected, - {"#server", kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( + kMetricConnected, {"#server", kXdsServer}, {}), ::testing::Optional(1)); - EXPECT_THAT(stats_plugin_->GetCounterValue(kMetricServerFailure, - {"#server", kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue(kMetricServerFailure, + {"#server", kXdsServer}, {}), absl::nullopt); for (absl::string_view type_url : {"envoy.config.listener.v3.Listener", "envoy.config.route.v3.RouteConfiguration"}) { EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesValid, - {"#server", kXdsServer, type_url}, {}), + stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesValid, {"#server", kXdsServer, type_url}, {}), ::testing::Optional(1)); + EXPECT_THAT(stats_plugin_->GetUInt64CounterValue( + kMetricResourceUpdatesInvalid, + {"#server", kXdsServer, type_url}, {}), + ::testing::Optional(0)); EXPECT_THAT( - stats_plugin_->GetCounterValue(kMetricResourceUpdatesInvalid, - {"#server", kXdsServer, type_url}, {}), - ::testing::Optional(0)); - EXPECT_THAT( - stats_plugin_->GetCallbackGaugeValue( + stats_plugin_->GetInt64CallbackGaugeValue( kMetricResources, {"#server", "#old", type_url, "acked"}, {}), ::testing::Optional(1)); } @@ -1269,8 +1269,8 @@ TEST_P(XdsMetricsTest, MetricValues) { const absl::Time deadline = absl::Now() + absl::Seconds(5 * grpc_test_slowdown_factor()); while (true) { - auto value = stats_plugin_->GetCounterValue(kMetricServerFailure, - {target, kXdsServer}, {}); + auto value = stats_plugin_->GetUInt64CounterValue( + kMetricServerFailure, {target, kXdsServer}, {}); if (value.has_value()) { EXPECT_EQ(1, *value); break; @@ -1279,8 +1279,8 @@ TEST_P(XdsMetricsTest, MetricValues) { absl::SleepFor(absl::Seconds(1)); } stats_plugin_->TriggerCallbacks(); - EXPECT_THAT(stats_plugin_->GetCallbackGaugeValue(kMetricConnected, - {target, kXdsServer}, {}), + EXPECT_THAT(stats_plugin_->GetInt64CallbackGaugeValue( + kMetricConnected, {target, kXdsServer}, {}), ::testing::Optional(0)); } } diff --git a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc index 84dc4865661..70188884d2e 100644 --- a/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc @@ -20,6 +20,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" @@ -313,14 +314,14 @@ TEST_P(RingHashTest, // Allow the connection attempt to complete. hold->Resume(); // Now the RPCs should complete successfully. - gpr_log(GPR_INFO, "=== WAITING FOR FIRST RPC TO FINISH ==="); + LOG(INFO) << "=== WAITING FOR FIRST RPC TO FINISH ==="; Status status = rpc.GetStatus(); - gpr_log(GPR_INFO, "=== FIRST RPC FINISHED ==="); + LOG(INFO) << "=== FIRST RPC FINISHED ==="; EXPECT_TRUE(status.ok()) << "code=" << status.error_code() << " message=" << status.error_message(); - gpr_log(GPR_INFO, "=== WAITING FOR SECOND RPC TO FINISH ==="); + LOG(INFO) << "=== WAITING FOR SECOND RPC TO FINISH ==="; status = rpc2.GetStatus(); - gpr_log(GPR_INFO, "=== SECOND RPC FINISHED ==="); + LOG(INFO) << "=== SECOND RPC FINISHED ==="; EXPECT_TRUE(status.ok()) << "code=" << status.error_code() << " message=" << status.error_message(); } @@ -1033,24 +1034,24 @@ TEST_P(RingHashTest, TransientFailureSkipToAvailableReady) { .set_metadata(std::move(metadata)) .set_timeout_ms(kConnectionTimeoutMilliseconds); EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false)); - gpr_log(GPR_INFO, "=== SENDING FIRST RPC ==="); + LOG(INFO) << "=== SENDING FIRST RPC ==="; CheckRpcSendFailure( DEBUG_LOCATION, StatusCode::UNAVAILABLE, MakeConnectionFailureRegex( "ring hash cannot find a connected endpoint; first failure: "), rpc_options); - gpr_log(GPR_INFO, "=== DONE WITH FIRST RPC ==="); + LOG(INFO) << "=== DONE WITH FIRST RPC ==="; EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel_->GetState(false)); // Bring up backend 0. The channel should become connected without // any picks, because in TF, we are always trying to connect to at // least one backend at all times. - gpr_log(GPR_INFO, "=== STARTING BACKEND 0 ==="); + LOG(INFO) << "=== STARTING BACKEND 0 ==="; StartBackend(0); - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO BECOME READY ==="); + LOG(INFO) << "=== WAITING FOR CHANNEL TO BECOME READY ==="; EXPECT_TRUE(channel_->WaitForConnected( grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds))); // RPCs should go to backend 0. - gpr_log(GPR_INFO, "=== WAITING FOR BACKEND 0 ==="); + LOG(INFO) << "=== WAITING FOR BACKEND 0 ==="; WaitForBackend(DEBUG_LOCATION, 0, /*check_status=*/nullptr, WaitForBackendOptions(), rpc_options); EXPECT_EQ(GRPC_CHANNEL_READY, channel_->GetState(false)); @@ -1062,28 +1063,28 @@ TEST_P(RingHashTest, TransientFailureSkipToAvailableReady) { // Since the the entries in the ring are pretty distributed and we have // unused ports to fill the ring, it is almost guaranteed that the Picker // will go through some non-READY entries and skip them as per design. - gpr_log(GPR_INFO, "=== SHUTTING DOWN BACKEND 0 ==="); + LOG(INFO) << "=== SHUTTING DOWN BACKEND 0 ==="; ShutdownBackend(0); - gpr_log(GPR_INFO, "=== WAITING FOR STATE CHANGE ==="); + LOG(INFO) << "=== WAITING FOR STATE CHANGE ==="; EXPECT_TRUE(channel_->WaitForStateChange( GRPC_CHANNEL_READY, grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds))); EXPECT_EQ(GRPC_CHANNEL_TRANSIENT_FAILURE, channel_->GetState(false)); - gpr_log(GPR_INFO, "=== SENDING SECOND RPC ==="); + LOG(INFO) << "=== SENDING SECOND RPC ==="; CheckRpcSendFailure( DEBUG_LOCATION, StatusCode::UNAVAILABLE, MakeConnectionFailureRegex( "ring hash cannot find a connected endpoint; first failure: "), rpc_options); - gpr_log(GPR_INFO, "=== STARTING BACKEND 1 ==="); + LOG(INFO) << "=== STARTING BACKEND 1 ==="; StartBackend(1); - gpr_log(GPR_INFO, "=== WAITING FOR CHANNEL TO BECOME READY ==="); + LOG(INFO) << "=== WAITING FOR CHANNEL TO BECOME READY ==="; EXPECT_TRUE(channel_->WaitForConnected( grpc_timeout_milliseconds_to_deadline(kConnectionTimeoutMilliseconds))); - gpr_log(GPR_INFO, "=== WAITING FOR BACKEND 1 ==="); + LOG(INFO) << "=== WAITING FOR BACKEND 1 ==="; WaitForBackend(DEBUG_LOCATION, 1, /*check_status=*/nullptr, WaitForBackendOptions(), rpc_options); - gpr_log(GPR_INFO, "=== DONE ==="); + LOG(INFO) << "=== DONE ==="; } // This tests a bug seen in the wild where ring_hash started with no diff --git a/test/cpp/end2end/xds/xds_server.h b/test/cpp/end2end/xds/xds_server.h index 1fa7d0cf3dd..20372a2a3be 100644 --- a/test/cpp/end2end/xds/xds_server.h +++ b/test/cpp/end2end/xds/xds_server.h @@ -24,6 +24,7 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/types/optional.h" #include @@ -233,16 +234,16 @@ class AdsServiceImpl Status StreamAggregatedResources(ServerContext* context, Stream* stream) override { - gpr_log(GPR_INFO, "ADS[%s]: StreamAggregatedResources starts", - debug_label_.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: StreamAggregatedResources starts"; { grpc_core::MutexLock lock(&ads_mu_); if (forced_ads_failure_.has_value()) { - gpr_log(GPR_INFO, - "ADS[%s]: StreamAggregatedResources forcing early failure " - "with status code: %d, message: %s", - debug_label_.c_str(), forced_ads_failure_.value().error_code(), - forced_ads_failure_.value().error_message().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: StreamAggregatedResources forcing early failure " + "with status code: " + << forced_ads_failure_.value().error_code() << ", message: " + << forced_ads_failure_.value().error_message(); return forced_ads_failure_.value(); } } @@ -283,10 +284,9 @@ class AdsServiceImpl DiscoveryRequest request = std::move(requests.front()); requests.pop_front(); did_work = true; - gpr_log(GPR_INFO, - "ADS[%s]: Received request for type %s with content %s", - debug_label_.c_str(), request.type_url().c_str(), - request.DebugString().c_str()); + LOG(INFO) << "ADS[" << debug_label_ << "]: Received request for type " + << request.type_url() << " with content " + << request.DebugString(); SentState& sent_state = sent_state_map[request.type_url()]; // Process request. ProcessRequest(request, &update_queue, &subscription_map, &sent_state, @@ -294,8 +294,8 @@ class AdsServiceImpl } } if (response.has_value()) { - gpr_log(GPR_INFO, "ADS[%s]: Sending response: %s", debug_label_.c_str(), - response->DebugString().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending response: " << response->DebugString(); stream->Write(response.value()); } response.reset(); @@ -315,8 +315,8 @@ class AdsServiceImpl } } if (response.has_value()) { - gpr_log(GPR_INFO, "ADS[%s]: Sending update response: %s", - debug_label_.c_str(), response->DebugString().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending update response: " << response->DebugString(); stream->Write(response.value()); } { @@ -350,8 +350,7 @@ class AdsServiceImpl } } } - gpr_log(GPR_INFO, "ADS[%s]: StreamAggregatedResources done", - debug_label_.c_str()); + LOG(INFO) << "ADS[" << debug_label_ << "]: StreamAggregatedResources done"; RemoveClient(context->peer()); return Status::OK; } @@ -382,9 +381,9 @@ class AdsServiceImpl ResponseState response_state; if (!request.has_error_detail()) { response_state.state = ResponseState::ACKED; - gpr_log(GPR_INFO, "ADS[%s]: client ACKed resource_type=%s version=%s", - debug_label_.c_str(), request.type_url().c_str(), - request.version_info().c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: client ACKed resource_type=" << request.type_url() + << " version=" << request.version_info(); } else { response_state.state = ResponseState::NACKED; if (check_nack_status_code_ != nullptr) { @@ -392,11 +391,10 @@ class AdsServiceImpl static_cast(request.error_detail().code())); } response_state.error_message = request.error_detail().message(); - gpr_log(GPR_INFO, - "ADS[%s]: client NACKed resource_type=%s version=%s: %s", - debug_label_.c_str(), request.type_url().c_str(), - request.version_info().c_str(), - response_state.error_message.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: client NACKed resource_type=" << request.type_url() + << " version=" << request.version_info() << ": " + << response_state.error_message; } resource_type_response_state_[request.type_url()].emplace_back( std::move(response_state)); @@ -426,9 +424,9 @@ class AdsServiceImpl &resource_state, update_queue) || ClientNeedsResourceUpdate(resource_type_state, resource_state, sent_state->resource_type_version)) { - gpr_log(GPR_INFO, "ADS[%s]: Sending update for type=%s name=%s", - debug_label_.c_str(), request.type_url().c_str(), - resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending update for type=" << request.type_url() + << " name=" << resource_name; resources_added_to_response.emplace(resource_name); if (!response->has_value()) response->emplace(); if (resource_state.resource.has_value()) { @@ -441,10 +439,9 @@ class AdsServiceImpl } } } else { - gpr_log(GPR_INFO, - "ADS[%s]: client does not need update for type=%s name=%s", - debug_label_.c_str(), request.type_url().c_str(), - resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: client does not need update for type=" + << request.type_url() << " name=" << resource_name; } } // Process unsubscriptions for any resource no longer @@ -467,8 +464,9 @@ class AdsServiceImpl SubscriptionMap* subscription_map, SentState* sent_state, absl::optional* response) ABSL_EXCLUSIVE_LOCKS_REQUIRED(ads_mu_) { - gpr_log(GPR_INFO, "ADS[%s]: Received update for type=%s name=%s", - debug_label_.c_str(), resource_type.c_str(), resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Received update for type=" << resource_type + << " name=" << resource_name; auto& subscription_name_map = (*subscription_map)[resource_type]; auto& resource_type_state = resource_map_[resource_type]; auto& resource_name_map = resource_type_state.resource_name_map; @@ -477,9 +475,9 @@ class AdsServiceImpl ResourceState& resource_state = resource_name_map[resource_name]; if (ClientNeedsResourceUpdate(resource_type_state, resource_state, sent_state->resource_type_version)) { - gpr_log(GPR_INFO, "ADS[%s]: Sending update for type=%s name=%s", - debug_label_.c_str(), resource_type.c_str(), - resource_name.c_str()); + LOG(INFO) << "ADS[" << debug_label_ + << "]: Sending update for type=" << resource_type + << " name=" << resource_name; response->emplace(); if (resource_state.resource.has_value()) { auto* resource = (*response)->add_resources(); @@ -510,8 +508,7 @@ class AdsServiceImpl requests->emplace_back(std::move(request)); } } - gpr_log(GPR_INFO, "ADS[%s]: Null read, stream closed", - debug_label_.c_str()); + LOG(INFO) << "ADS[" << debug_label_ << "]: Null read, stream closed"; grpc_core::MutexLock lock(&ads_mu_); *stream_closed = true; } @@ -751,7 +748,7 @@ class LrsServiceImpl using Stream = ServerReaderWriter; Status StreamLoadStats(ServerContext* /*context*/, Stream* stream) override { - gpr_log(GPR_INFO, "LRS[%s]: StreamLoadStats starts", debug_label_.c_str()); + LOG(INFO) << "LRS[" << debug_label_ << "]: StreamLoadStats starts"; if (stream_started_callback_ != nullptr) stream_started_callback_(); // Take a reference of the LrsServiceImpl object, reference will go // out of scope after this method exits. @@ -778,8 +775,9 @@ class LrsServiceImpl // Wait for report. request.Clear(); while (stream->Read(&request)) { - gpr_log(GPR_INFO, "LRS[%s]: received client load report message: %s", - debug_label_.c_str(), request.DebugString().c_str()); + LOG(INFO) << "LRS[" << debug_label_ + << "]: received client load report message: " + << request.DebugString(); std::vector stats; for (const auto& cluster_stats : request.cluster_stats()) { stats.emplace_back(cluster_stats); @@ -796,7 +794,7 @@ class LrsServiceImpl lrs_cv_.Wait(&lrs_mu_); } } - gpr_log(GPR_INFO, "LRS[%s]: StreamLoadStats done", debug_label_.c_str()); + LOG(INFO) << "LRS[" << debug_label_ << "]: StreamLoadStats done"; return Status::OK; } diff --git a/test/cpp/end2end/xds/xds_wrr_end2end_test.cc b/test/cpp/end2end/xds/xds_wrr_end2end_test.cc index 97c5b6ab9a1..9a58443efa0 100644 --- a/test/cpp/end2end/xds/xds_wrr_end2end_test.cc +++ b/test/cpp/end2end/xds/xds_wrr_end2end_test.cc @@ -132,12 +132,12 @@ TEST_P(WrrTest, MetricsHaveLocalityLabel) { WaitForAllBackends(DEBUG_LOCATION); // Make sure we have a metric value for each of the two localities. EXPECT_THAT( - stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues, - {LocalityNameString("locality0")}), + stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues, + {LocalityNameString("locality0")}), ::testing::Optional(::testing::Not(::testing::IsEmpty()))); EXPECT_THAT( - stats_plugin->GetHistogramValue(kEndpointWeights, kLabelValues, - {LocalityNameString("locality1")}), + stats_plugin->GetDoubleHistogramValue(kEndpointWeights, kLabelValues, + {LocalityNameString("locality1")}), ::testing::Optional(::testing::Not(::testing::IsEmpty()))); } diff --git a/test/cpp/ext/csm/metadata_exchange_test.cc b/test/cpp/ext/csm/metadata_exchange_test.cc index 0a37a1cbc1d..aeaad05117d 100644 --- a/test/cpp/ext/csm/metadata_exchange_test.cc +++ b/test/cpp/ext/csm/metadata_exchange_test.cc @@ -397,6 +397,9 @@ TEST_P(MetadataExchangeTest, ClientDoesNotSendMetadata) { EXPECT_EQ(absl::get(attributes.at("csm.mesh_id")), "mesh-id"); EXPECT_EQ(absl::get(attributes.at("csm.remote_workload_type")), "unknown"); + EXPECT_EQ(absl::get( + attributes.at("csm.remote_workload_canonical_service")), + "unknown"); } TEST_P(MetadataExchangeTest, VerifyCsmServiceLabels) { @@ -424,6 +427,8 @@ TEST_P(MetadataExchangeTest, VerifyCsmServiceLabels) { "mynamespace"); } +// Test that metadata exchange works and corresponding service mesh labels are +// received and recorded even if the server sends a trailers-only response. TEST_P(MetadataExchangeTest, Retries) { Init(std::move( Options() diff --git a/test/cpp/ext/filters/census/BUILD b/test/cpp/ext/filters/census/BUILD index 1be8dfe81e8..967d9da6e79 100644 --- a/test/cpp/ext/filters/census/BUILD +++ b/test/cpp/ext/filters/census/BUILD @@ -51,6 +51,7 @@ grpc_cc_test( "stats_plugin_end2end_test.cc", ], external_deps = [ + "absl/log:log", "gtest", "opencensus-stats-test", "opencensus-tags", diff --git a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc index a700810a3ea..916718c5a7c 100644 --- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc +++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc @@ -20,6 +20,7 @@ #include // NOLINT #include +#include "absl/log/log.h" #include "absl/strings/str_cat.h" #include "absl/strings/string_view.h" #include "gmock/gmock.h" @@ -517,8 +518,8 @@ TEST_F(StatsPluginEnd2EndTest, TestRetryStatsWithAdditionalRetries) { ::testing::ElementsAre(client_method_name_), ::testing::Eq(0)))); auto data = client_retry_delay_per_call_view.GetData().distribution_data(); for (const auto& entry : data) { - gpr_log(GPR_ERROR, "Mean Retry Delay %s: %lf ms", entry.first[0].c_str(), - entry.second.mean()); + LOG(ERROR) << "Mean Retry Delay " << entry.first[0] << ": " + << entry.second.mean() << " ms"; } // We expect the retry delay to be around 100ms. EXPECT_THAT( @@ -1007,95 +1008,94 @@ TEST_F(StatsPluginEnd2EndTest, TestGlobalEnableOpenCensusTracing) { // This test verifies that users depending on src/cpp/ext/filters/census header // files can continue using the non-experimental names. TEST(StatsPluginDeclarationTest, Declarations) { - gpr_log(GPR_INFO, "%p", ClientMethodTagKey); - gpr_log(GPR_INFO, "%p", ClientStatusTagKey); - gpr_log(GPR_INFO, "%p", ServerMethodTagKey); - gpr_log(GPR_INFO, "%p", ServerStatusTagKey); - - gpr_log(GPR_INFO, "%p", kRpcClientReceivedBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientReceivedMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientRetriesPerCallMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientRetryDelayPerCallMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientRoundtripLatencyMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientSentBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientSentMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientServerLatencyMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcClientStartedRpcsMeasureName.data()); - gpr_log(GPR_INFO, "%p", - kRpcClientTransparentRetriesPerCallMeasureName.data()); - - gpr_log(GPR_INFO, "%p", kRpcServerReceivedBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerReceivedMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerSentBytesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerSentMessagesPerRpcMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerServerLatencyMeasureName.data()); - gpr_log(GPR_INFO, "%p", kRpcServerStartedRpcsMeasureName.data()); - - gpr_log(GPR_INFO, "%p", ClientCompletedRpcsCumulative); - gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientRetriesCumulative); - gpr_log(GPR_INFO, "%p", ClientRetriesPerCallCumulative); - gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallCumulative); - gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyCumulative); - gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ClientServerLatencyCumulative); - gpr_log(GPR_INFO, "%p", ClientStartedRpcsCumulative); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesCumulative); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallCumulative); - - gpr_log(GPR_INFO, "%p", ServerCompletedRpcsCumulative); - gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcCumulative); - gpr_log(GPR_INFO, "%p", ServerServerLatencyCumulative); - gpr_log(GPR_INFO, "%p", ServerStartedRpcsCumulative); - - gpr_log(GPR_INFO, "%p", ClientCompletedRpcsMinute); - gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientRetriesMinute); - gpr_log(GPR_INFO, "%p", ClientRetriesPerCallMinute); - gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallMinute); - gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyMinute); - gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ClientServerLatencyMinute); - gpr_log(GPR_INFO, "%p", ClientStartedRpcsMinute); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesMinute); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallMinute); - - gpr_log(GPR_INFO, "%p", ServerCompletedRpcsMinute); - gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcMinute); - gpr_log(GPR_INFO, "%p", ServerServerLatencyMinute); - gpr_log(GPR_INFO, "%p", ServerStartedRpcsMinute); - - gpr_log(GPR_INFO, "%p", ClientCompletedRpcsHour); - gpr_log(GPR_INFO, "%p", ClientReceivedBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientReceivedMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientRetriesHour); - gpr_log(GPR_INFO, "%p", ClientRetriesPerCallHour); - gpr_log(GPR_INFO, "%p", ClientRetryDelayPerCallHour); - gpr_log(GPR_INFO, "%p", ClientRoundtripLatencyHour); - gpr_log(GPR_INFO, "%p", ClientSentBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientSentMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ClientServerLatencyHour); - gpr_log(GPR_INFO, "%p", ClientStartedRpcsHour); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesHour); - gpr_log(GPR_INFO, "%p", ClientTransparentRetriesPerCallHour); - - gpr_log(GPR_INFO, "%p", ServerCompletedRpcsHour); - gpr_log(GPR_INFO, "%p", ServerReceivedBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerReceivedMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerSentBytesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerSentMessagesPerRpcHour); - gpr_log(GPR_INFO, "%p", ServerServerLatencyHour); - gpr_log(GPR_INFO, "%p", ServerStartedRpcsHour); + LOG(INFO) << ClientMethodTagKey; + LOG(INFO) << ClientStatusTagKey; + LOG(INFO) << ServerMethodTagKey; + LOG(INFO) << ServerStatusTagKey; + + LOG(INFO) << kRpcClientReceivedBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientReceivedMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientRetriesPerCallMeasureName.data(); + LOG(INFO) << kRpcClientRetryDelayPerCallMeasureName.data(); + LOG(INFO) << kRpcClientRoundtripLatencyMeasureName.data(); + LOG(INFO) << kRpcClientSentBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientSentMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcClientServerLatencyMeasureName.data(); + LOG(INFO) << kRpcClientStartedRpcsMeasureName.data(); + LOG(INFO) << kRpcClientTransparentRetriesPerCallMeasureName.data(); + + LOG(INFO) << kRpcServerReceivedBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerReceivedMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerSentBytesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerSentMessagesPerRpcMeasureName.data(); + LOG(INFO) << kRpcServerServerLatencyMeasureName.data(); + LOG(INFO) << kRpcServerStartedRpcsMeasureName.data(); + + LOG(INFO) << ClientCompletedRpcsCumulative; + LOG(INFO) << ClientReceivedBytesPerRpcCumulative; + LOG(INFO) << ClientReceivedMessagesPerRpcCumulative; + LOG(INFO) << ClientRetriesCumulative; + LOG(INFO) << ClientRetriesPerCallCumulative; + LOG(INFO) << ClientRetryDelayPerCallCumulative; + LOG(INFO) << ClientRoundtripLatencyCumulative; + LOG(INFO) << ClientSentBytesPerRpcCumulative; + LOG(INFO) << ClientSentMessagesPerRpcCumulative; + LOG(INFO) << ClientServerLatencyCumulative; + LOG(INFO) << ClientStartedRpcsCumulative; + LOG(INFO) << ClientTransparentRetriesCumulative; + LOG(INFO) << ClientTransparentRetriesPerCallCumulative; + + LOG(INFO) << ServerCompletedRpcsCumulative; + LOG(INFO) << ServerReceivedBytesPerRpcCumulative; + LOG(INFO) << ServerReceivedMessagesPerRpcCumulative; + LOG(INFO) << ServerSentBytesPerRpcCumulative; + LOG(INFO) << ServerSentMessagesPerRpcCumulative; + LOG(INFO) << ServerServerLatencyCumulative; + LOG(INFO) << ServerStartedRpcsCumulative; + + LOG(INFO) << ClientCompletedRpcsMinute; + LOG(INFO) << ClientReceivedBytesPerRpcMinute; + LOG(INFO) << ClientReceivedMessagesPerRpcMinute; + LOG(INFO) << ClientRetriesMinute; + LOG(INFO) << ClientRetriesPerCallMinute; + LOG(INFO) << ClientRetryDelayPerCallMinute; + LOG(INFO) << ClientRoundtripLatencyMinute; + LOG(INFO) << ClientSentBytesPerRpcMinute; + LOG(INFO) << ClientSentMessagesPerRpcMinute; + LOG(INFO) << ClientServerLatencyMinute; + LOG(INFO) << ClientStartedRpcsMinute; + LOG(INFO) << ClientTransparentRetriesMinute; + LOG(INFO) << ClientTransparentRetriesPerCallMinute; + + LOG(INFO) << ServerCompletedRpcsMinute; + LOG(INFO) << ServerReceivedBytesPerRpcMinute; + LOG(INFO) << ServerReceivedMessagesPerRpcMinute; + LOG(INFO) << ServerSentBytesPerRpcMinute; + LOG(INFO) << ServerSentMessagesPerRpcMinute; + LOG(INFO) << ServerServerLatencyMinute; + LOG(INFO) << ServerStartedRpcsMinute; + + LOG(INFO) << ClientCompletedRpcsHour; + LOG(INFO) << ClientReceivedBytesPerRpcHour; + LOG(INFO) << ClientReceivedMessagesPerRpcHour; + LOG(INFO) << ClientRetriesHour; + LOG(INFO) << ClientRetriesPerCallHour; + LOG(INFO) << ClientRetryDelayPerCallHour; + LOG(INFO) << ClientRoundtripLatencyHour; + LOG(INFO) << ClientSentBytesPerRpcHour; + LOG(INFO) << ClientSentMessagesPerRpcHour; + LOG(INFO) << ClientServerLatencyHour; + LOG(INFO) << ClientStartedRpcsHour; + LOG(INFO) << ClientTransparentRetriesHour; + LOG(INFO) << ClientTransparentRetriesPerCallHour; + + LOG(INFO) << ServerCompletedRpcsHour; + LOG(INFO) << ServerReceivedBytesPerRpcHour; + LOG(INFO) << ServerReceivedMessagesPerRpcHour; + LOG(INFO) << ServerSentBytesPerRpcHour; + LOG(INFO) << ServerSentMessagesPerRpcHour; + LOG(INFO) << ServerServerLatencyHour; + LOG(INFO) << ServerStartedRpcsHour; } } // namespace diff --git a/test/cpp/ext/otel/otel_plugin_test.cc b/test/cpp/ext/otel/otel_plugin_test.cc index af24fcabcac..e616f075d13 100644 --- a/test/cpp/ext/otel/otel_plugin_test.cc +++ b/test/cpp/ext/otel/otel_plugin_test.cc @@ -1263,7 +1263,7 @@ using OpenTelemetryPluginNPCMetricsTest = OpenTelemetryPluginEnd2EndTest; TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) { constexpr absl::string_view kMetricName = "uint64_counter"; - constexpr int kCounterValues[] = {1, 2, 3}; + constexpr uint64_t kCounterValues[] = {1, 2, 3}; constexpr int64_t kCounterResult = 6; constexpr std::array kLabelKeys = {"label_key_1", "label_key_2"}; @@ -1273,9 +1273,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Counter) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter( - kMetricName, "A simple uint64 counter.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Counter( + kMetricName, "A simple uint64 counter.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kMetricName}) .set_channel_scope_filter( @@ -1319,9 +1323,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter( - kMetricName, "A simple double counter.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/false); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleCounter( + kMetricName, "A simple double counter.", "unit", + /*enable_by_default=*/false) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kMetricName}) .set_channel_scope_filter( @@ -1355,7 +1363,7 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleCounter) { TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) { constexpr absl::string_view kMetricName = "uint64_histogram"; - constexpr int kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6}; + constexpr uint64_t kHistogramValues[] = {1, 1, 2, 3, 4, 4, 5, 6}; constexpr int64_t kSum = 26; constexpr int64_t kMin = 1; constexpr int64_t kMax = 6; @@ -1368,9 +1376,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordUInt64Histogram) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram( - kMetricName, "A simple uint64 histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterUInt64Histogram( + kMetricName, "A simple uint64 histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move( Options() .set_metric_names({kMetricName}) @@ -1419,9 +1431,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, RecordDoubleHistogram) { "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( - kMetricName, "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( + kMetricName, "A simple double histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move( Options() .set_metric_names({kMetricName}) @@ -1466,9 +1482,13 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, "label_value_2"}; constexpr std::array kOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( - kMetricName, "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( + kMetricName, "A simple double histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); // Build and register a separate OpenTelemetryPlugin and verify its histogram // recording. grpc::internal::OpenTelemetryPluginBuilderImpl ot_builder; @@ -1592,9 +1612,14 @@ TEST_F(OpenTelemetryPluginNPCMetricsTest, constexpr std::array kActualOptionalLabelValues = { "optional_label_value_1", "optional_label_value_2", "optional_label_value_4"}; - auto handle = grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( - kMetricName, "A simple double histogram.", "unit", kLabelKeys, - kOptionalLabelKeys, /*enable_by_default=*/true); + auto handle = + grpc_core::GlobalInstrumentsRegistry::RegisterDoubleHistogram( + kMetricName, "A simple double histogram.", "unit", + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1], + kOptionalLabelKeys[2], kOptionalLabelKeys[3]) + .Build(); Init(std::move( Options() .set_metric_names({kMetricName}) @@ -1655,13 +1680,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, auto integer_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); auto double_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kInt64CallbackGaugeMetric, kDoubleCallbackGaugeMetric}) @@ -1671,8 +1700,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel( grpc_core::experimental::StatsPluginChannelScope( "dns:///localhost:8080", "")); - // Multiple callbacks for the same metrics, each reporting different label - // values. + // Multiple callbacks for the same metrics, each reporting different + // label values. int report_count_1 = 0; int64_t int_value_1 = 1; double double_value_1 = 0.5; @@ -1688,8 +1717,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); int report_count_2 = 0; int64_t int_value_2 = 1; double double_value_2 = 0.5; @@ -1705,8 +1734,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(100) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); constexpr int kIterations = 100; MetricsCollectorThread collector{ this, grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(), @@ -1786,13 +1815,17 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, auto integer_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackInt64Gauge( kInt64CallbackGaugeMetric, "An int64 callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); auto double_gauge_handle = grpc_core::GlobalInstrumentsRegistry::RegisterCallbackDoubleGauge( kDoubleCallbackGaugeMetric, "A double callback gauge.", "unit", - kLabelKeys, kOptionalLabelKeys, - /*enable_by_default=*/true); + /*enable_by_default=*/true) + .Labels(kLabelKeys[0], kLabelKeys[1]) + .OptionalLabels(kOptionalLabelKeys[0], kOptionalLabelKeys[1]) + .Build(); Init(std::move(Options() .set_metric_names({kInt64CallbackGaugeMetric, kDoubleCallbackGaugeMetric}) @@ -1802,8 +1835,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, grpc_core::GlobalStatsPluginRegistry::GetStatsPluginsForChannel( grpc_core::experimental::StatsPluginChannelScope( "dns:///localhost:8080", "")); - // Multiple callbacks for the same metrics, each reporting different label - // values. + // Multiple callbacks for the same metrics, each reporting different + // label values. int report_count_1 = 0; int64_t int_value_1 = 1; double double_value_1 = 0.5; @@ -1819,8 +1852,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_1++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); int report_count_2 = 0; int64_t int_value_2 = 1; double double_value_2 = 0.5; @@ -1836,8 +1869,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, reporter.Report(double_gauge_handle, double_value_2++, kLabelValuesSet2, kOptionalLabelValuesSet2); }, - {integer_gauge_handle, double_gauge_handle}, - grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor()); + grpc_core::Duration::Milliseconds(10) * grpc_test_slowdown_factor(), + integer_gauge_handle, double_gauge_handle); constexpr int kIterations = 100; MetricsCollectorThread collector{ this, @@ -1854,7 +1887,8 @@ TEST_F(OpenTelemetryPluginCallbackMetricsTest, std::string, std::vector> data = collector.Stop(); - // Verify that data is incremental without duplications (cached values). + // Verify that data is incremental without duplications (cached + // values). EXPECT_EQ(report_count_1, kIterations); EXPECT_EQ(report_count_2, kIterations); EXPECT_EQ(data[kInt64CallbackGaugeMetric].size(), diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 76b49f88be9..21d86d04971 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -46,6 +46,7 @@ grpc_cc_binary( external_deps = [ "absl/flags:flag", "absl/log:check", + "absl/log:log", "absl/time:time", ], language = "C++", @@ -429,6 +430,7 @@ grpc_cc_binary( external_deps = [ "absl/flags:flag", "absl/log:check", + "absl/log:log", ], deps = [ "//:grpc++", diff --git a/test/cpp/interop/grpclb_fallback_test.cc b/test/cpp/interop/grpclb_fallback_test.cc index c8e20fdc54e..331885e8c0f 100644 --- a/test/cpp/interop/grpclb_fallback_test.cc +++ b/test/cpp/interop/grpclb_fallback_test.cc @@ -32,11 +32,11 @@ #include "absl/flags/flag.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_format.h" #include "absl/time/time.h" #include -#include #include #include #include @@ -87,8 +87,8 @@ enum RpcMode { GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds, RpcMode rpc_mode) { - gpr_log(GPR_INFO, "DoRPCAndGetPath deadline_seconds:%d rpc_mode:%d", - deadline_seconds, rpc_mode); + LOG(INFO) << "DoRPCAndGetPath deadline_seconds:" << deadline_seconds + << " rpc_mode:" << rpc_mode; SimpleRequest request; SimpleResponse response; grpc::ClientContext context; @@ -101,16 +101,16 @@ GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds, context.set_deadline(deadline); grpc::Status s = stub->UnaryCall(&context, request, &response); if (!s.ok()) { - gpr_log(GPR_INFO, "DoRPCAndGetPath failed. status-message: %s", - s.error_message().c_str()); + LOG(INFO) << "DoRPCAndGetPath failed. status-message: " + << s.error_message(); return GrpclbRouteType::GRPCLB_ROUTE_TYPE_UNKNOWN; } CHECK(response.grpclb_route_type() == GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND || response.grpclb_route_type() == GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK); - gpr_log(GPR_INFO, "DoRPCAndGetPath done. grpclb_route_type:%d", - response.grpclb_route_type()); + LOG(INFO) << "DoRPCAndGetPath done. grpclb_route_type:" + << response.grpclb_route_type(); return response.grpclb_route_type(); } @@ -120,7 +120,7 @@ GrpclbRouteType DoRPCAndGetPath(TestService::Stub* stub, int deadline_seconds) { bool TcpUserTimeoutMutateFd(int fd, grpc_socket_mutator* /*mutator*/) { int timeout = 20000; // 20 seconds - gpr_log(GPR_INFO, "Setting socket option TCP_USER_TIMEOUT on fd: %d", fd); + LOG(INFO) << "Setting socket option TCP_USER_TIMEOUT on fd: " << fd; if (0 != setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, &timeout, sizeof(timeout))) { grpc_core::Crash("Failed to set socket option TCP_USER_TIMEOUT"); @@ -161,7 +161,7 @@ std::unique_ptr CreateFallbackTestStub() { } void RunCommand(const std::string& command) { - gpr_log(GPR_INFO, "RunCommand: |%s|", command.c_str()); + LOG(INFO) << "RunCommand: |" << command << "|"; int out = std::system(command.c_str()); if (WIFEXITED(out)) { int code = WEXITSTATUS(out); @@ -185,25 +185,23 @@ void WaitForFallbackAndDoRPCs(TestService::Stub* stub) { while (absl::Now() < fallback_deadline) { GrpclbRouteType grpclb_route_type = DoRPCAndGetPath(stub, 1); if (grpclb_route_type == GrpclbRouteType::GRPCLB_ROUTE_TYPE_BACKEND) { - gpr_log(GPR_ERROR, - "Got grpclb route type backend. Backends are " - "supposed to be unreachable, so this test is broken"); + LOG(ERROR) << "Got grpclb route type backend. Backends are " + "supposed to be unreachable, so this test is broken"; CHECK(0); } if (grpclb_route_type == GrpclbRouteType::GRPCLB_ROUTE_TYPE_FALLBACK) { - gpr_log(GPR_INFO, - "Made one successful RPC to a fallback. Now expect the same for " - "the rest."); + LOG(INFO) << "Made one successful RPC to a fallback. Now expect the same " + "for the rest."; fallback = true; break; } else { - gpr_log(GPR_ERROR, "Retryable RPC failure on iteration: %d", - fallback_retry_count); + LOG(ERROR) << "Retryable RPC failure on iteration: " + << fallback_retry_count; } fallback_retry_count++; } if (!fallback) { - gpr_log(GPR_ERROR, "Didn't fall back within deadline"); + LOG(ERROR) << "Didn't fall back within deadline"; CHECK(0); } for (int i = 0; i < 30; i++) { @@ -231,13 +229,13 @@ void DoFallbackAfterStartupTest() { int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); - gpr_log(GPR_INFO, "Testing: %s", absl::GetFlag(FLAGS_test_case).c_str()); + LOG(INFO) << "Testing: " << absl::GetFlag(FLAGS_test_case); if (absl::GetFlag(FLAGS_test_case) == "fallback_before_startup") { DoFallbackBeforeStartupTest(); - gpr_log(GPR_INFO, "DoFallbackBeforeStartup done!"); + LOG(INFO) << "DoFallbackBeforeStartup done!"; } else if (absl::GetFlag(FLAGS_test_case) == "fallback_after_startup") { DoFallbackAfterStartupTest(); - gpr_log(GPR_INFO, "DoFallbackBeforeStartup done!"); + LOG(INFO) << "DoFallbackBeforeStartup done!"; } else { grpc_core::Crash(absl::StrFormat("Invalid test case: %s", absl::GetFlag(FLAGS_test_case).c_str())); diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc index eb96a08b715..89477f3cd51 100644 --- a/test/cpp/interop/http2_client.cc +++ b/test/cpp/interop/http2_client.cc @@ -22,10 +22,10 @@ #include "absl/flags/flag.h" #include "absl/log/check.h" +#include "absl/log/log.h" #include "absl/strings/str_format.h" #include -#include #include #include @@ -81,40 +81,40 @@ SimpleRequest Http2Client::BuildDefaultRequest() { } bool Http2Client::DoRstAfterHeader() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header"); + VLOG(2) << "Sending RPC and expecting reset stream after header"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); CHECK(!response.has_payload()); // no data should be received - gpr_log(GPR_DEBUG, "Done testing reset stream after header"); + VLOG(2) << "Done testing reset stream after header"; return true; } bool Http2Client::DoRstAfterData() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after data"); + VLOG(2) << "Sending RPC and expecting reset stream after data"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); // There is no guarantee that data would be received. - gpr_log(GPR_DEBUG, "Done testing reset stream after data"); + VLOG(2) << "Done testing reset stream after data"; return true; } bool Http2Client::DoRstDuringData() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream during data"); + VLOG(2) << "Sending RPC and expecting reset stream during data"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL); CHECK(!response.has_payload()); // no data should be received - gpr_log(GPR_DEBUG, "Done testing reset stream during data"); + VLOG(2) << "Done testing reset stream during data"; return true; } bool Http2Client::DoGoaway() { - gpr_log(GPR_DEBUG, "Sending two RPCs and expecting goaway"); + VLOG(2) << "Sending two RPCs and expecting goaway"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0')); @@ -127,16 +127,16 @@ bool Http2Client::DoGoaway() { response.Clear(); AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0')); - gpr_log(GPR_DEBUG, "Done testing goaway"); + VLOG(2) << "Done testing goaway"; return true; } bool Http2Client::DoPing() { - gpr_log(GPR_DEBUG, "Sending RPC and expecting ping"); + VLOG(2) << "Sending RPC and expecting ping"; SimpleResponse response; AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK); CHECK(response.payload().body() == std::string(kLargeResponseSize, '\0')); - gpr_log(GPR_DEBUG, "Done testing ping"); + VLOG(2) << "Done testing ping"; return true; } @@ -148,7 +148,7 @@ void Http2Client::MaxStreamsWorker( } bool Http2Client::DoMaxStreams() { - gpr_log(GPR_DEBUG, "Testing max streams"); + VLOG(2) << "Testing max streams"; // Make an initial call on the channel to ensure the server's max streams // setting is received @@ -167,7 +167,7 @@ bool Http2Client::DoMaxStreams() { it->join(); } - gpr_log(GPR_DEBUG, "Done testing max streams"); + VLOG(2) << "Done testing max streams"; return true; } @@ -198,7 +198,7 @@ int main(int argc, char** argv) { CHECK(channel->WaitForConnected(gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN)))); grpc::testing::Http2Client client(channel); - gpr_log(GPR_INFO, "Testing case: %s", absl::GetFlag(FLAGS_test_case).c_str()); + LOG(INFO) << "Testing case: " << absl::GetFlag(FLAGS_test_case); int ret = 0; if (absl::GetFlag(FLAGS_test_case) == "rst_after_header") { client.DoRstAfterHeader(); @@ -219,8 +219,9 @@ int main(int argc, char** argv) { char* joined_testcases = gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", nullptr); - gpr_log(GPR_ERROR, "Unsupported test case %s. Valid options are\n%s", - absl::GetFlag(FLAGS_test_case).c_str(), joined_testcases); + LOG(ERROR) << "Unsupported test case " << absl::GetFlag(FLAGS_test_case) + << ". Valid options are\n" + << joined_testcases; gpr_free(joined_testcases); ret = 1; } diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc index 04a8f010cd5..b79df3ed4d1 100644 --- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc +++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong_chaotic_good.cc @@ -111,7 +111,6 @@ int main(int argc, char** argv) { grpc_core::ForceEnableExperiment("event_engine_client", true); grpc_core::ForceEnableExperiment("event_engine_listener", true); grpc_core::ForceEnableExperiment("promise_based_client_call", true); - grpc_core::ForceEnableExperiment("promise_based_server_call", true); grpc_core::ForceEnableExperiment("chaotic_good", true); grpc::testing::TestEnvironment env(&argc, argv); LibraryInitializer libInit; diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD index 53292ea0a74..554f29fea62 100644 --- a/test/cpp/qps/BUILD +++ b/test/cpp/qps/BUILD @@ -77,7 +77,10 @@ grpc_cc_library( "driver.h", "report.h", ], - external_deps = ["absl/log:check"], + external_deps = [ + "absl/log:check", + "absl/log:log", + ], deps = [ ":histogram", ":parse_json", diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 5c5887c65b5..e8ee2da4539 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -26,10 +26,10 @@ #include #include "absl/log/check.h" +#include "absl/log/log.h" #include "google/protobuf/timestamp.pb.h" #include -#include #include #include #include @@ -78,13 +78,13 @@ static deque get_workers(const string& env_name) { } } if (out.empty()) { - gpr_log(GPR_ERROR, - "Environment variable \"%s\" does not contain a list of QPS " - "workers to use. Set it to a comma-separated list of " - "hostname:port pairs, starting with hosts that should act as " - "servers. E.g. export " - "%s=\"serverhost1:1234,clienthost1:1234,clienthost2:1234\"", - env_name.c_str(), env_name.c_str()); + LOG(ERROR) << "Environment variable \"" << env_name + << "\" does not contain a list of QPS " + "workers to use. Set it to a comma-separated list of " + "hostname:port pairs, starting with hosts that should act as " + "servers. E.g. export " + << env_name + << "=\"serverhost1:1234,clienthost1:1234,clienthost2:1234\""; } return out; } @@ -237,7 +237,7 @@ struct ServerData { static void FinishClients(const std::vector& clients, const ClientArgs& client_mark) { - gpr_log(GPR_INFO, "Finishing clients"); + LOG(INFO) << "Finishing clients"; for (size_t i = 0, i_end = clients.size(); i < i_end; i++) { auto client = &clients[i]; if (!client->stream->Write(client_mark)) { @@ -252,13 +252,13 @@ static void FinishClients(const std::vector& clients, static void ReceiveFinalStatusFromClients( const std::vector& clients, Histogram& merged_latencies, std::unordered_map& merged_statuses, ScenarioResult& result) { - gpr_log(GPR_INFO, "Receiving final status from clients"); + LOG(INFO) << "Receiving final status from clients"; ClientStatus client_status; for (size_t i = 0, i_end = clients.size(); i < i_end; i++) { auto client = &clients[i]; // Read the client final status if (client->stream->Read(&client_status)) { - gpr_log(GPR_INFO, "Received final status from client %zu", i); + LOG(INFO) << "Received final status from client " << i; const auto& stats = client_status.stats(); merged_latencies.MergeProto(stats.latencies()); for (int i = 0; i < stats.request_results_size(); i++) { @@ -282,7 +282,7 @@ static void ReceiveFinalStatusFromClients( static void ShutdownClients(const std::vector& clients, ScenarioResult& result) { - gpr_log(GPR_INFO, "Shutdown clients"); + LOG(INFO) << "Shutdown clients"; for (size_t i = 0, i_end = clients.size(); i < i_end; i++) { auto client = &clients[i]; Status s = client->stream->Finish(); @@ -300,7 +300,7 @@ static void ShutdownClients(const std::vector& clients, static void FinishServers(const std::vector& servers, const ServerArgs& server_mark) { - gpr_log(GPR_INFO, "Finishing servers"); + LOG(INFO) << "Finishing servers"; for (size_t i = 0, i_end = servers.size(); i < i_end; i++) { auto server = &servers[i]; if (!server->stream->Write(server_mark)) { @@ -314,13 +314,13 @@ static void FinishServers(const std::vector& servers, static void ReceiveFinalStatusFromServer(const std::vector& servers, ScenarioResult& result) { - gpr_log(GPR_INFO, "Receiving final status from servers"); + LOG(INFO) << "Receiving final status from servers"; ServerStatus server_status; for (size_t i = 0, i_end = servers.size(); i < i_end; i++) { auto server = &servers[i]; // Read the server final status if (server->stream->Read(&server_status)) { - gpr_log(GPR_INFO, "Received final status from server %zu", i); + LOG(INFO) << "Received final status from server " << i; result.add_server_stats()->CopyFrom(server_status.stats()); result.add_server_cores(server_status.cores()); // That final status should be the last message on the server stream @@ -334,7 +334,7 @@ static void ReceiveFinalStatusFromServer(const std::vector& servers, static void ShutdownServers(const std::vector& servers, ScenarioResult& result) { - gpr_log(GPR_INFO, "Shutdown servers"); + LOG(INFO) << "Shutdown servers"; for (size_t i = 0, i_end = servers.size(); i < i_end; i++) { auto server = &servers[i]; Status s = server->stream->Finish(); @@ -430,8 +430,8 @@ std::unique_ptr RunScenario( ChannelArguments channel_args; for (size_t i = 0; i < num_servers; i++) { - gpr_log(GPR_INFO, "Starting server on %s (worker #%" PRIuPTR ")", - workers[i].c_str(), i); + LOG(INFO) << "Starting server on " << workers[i] << " (worker #" << i + << ")"; if (!run_inproc) { servers[i].stub = WorkerService::NewStub(grpc::CreateTestChannel( workers[i], @@ -487,8 +487,8 @@ std::unique_ptr RunScenario( size_t channels_allocated = 0; for (size_t i = 0; i < num_clients; i++) { const auto& worker = workers[i + num_servers]; - gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")", - worker.c_str(), i + num_servers); + LOG(INFO) << "Starting client on " << worker << " (worker #" + << i + num_servers << ")"; if (!run_inproc) { clients[i].stub = WorkerService::NewStub(grpc::CreateTestChannel( worker, @@ -510,8 +510,7 @@ std::unique_ptr RunScenario( (client_config.client_channels() - channels_allocated) / (num_clients - i); channels_allocated += num_channels; - gpr_log(GPR_DEBUG, "Client %" PRIdPTR " gets %" PRIdPTR " channels", i, - num_channels); + VLOG(2) << "Client " << i << " gets " << num_channels << " channels"; per_client_config.set_client_channels(num_channels); ClientArgs args; @@ -533,7 +532,7 @@ std::unique_ptr RunScenario( // Send an initial mark: clients can use this to know that everything is ready // to start - gpr_log(GPR_INFO, "Initiating"); + LOG(INFO) << "Initiating"; ServerArgs server_mark; server_mark.mutable_mark()->set_reset(true); ClientArgs client_mark; @@ -555,13 +554,13 @@ std::unique_ptr RunScenario( } // Let everything warmup - gpr_log(GPR_INFO, "Warming up"); + LOG(INFO) << "Warming up"; gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); gpr_sleep_until( gpr_time_add(start, gpr_time_from_seconds(warmup_seconds, GPR_TIMESPAN))); // Start a run - gpr_log(GPR_INFO, "Starting"); + LOG(INFO) << "Starting"; auto start_time = time(nullptr); @@ -593,7 +592,7 @@ std::unique_ptr RunScenario( } // Wait some time - gpr_log(GPR_INFO, "Running"); + LOG(INFO) << "Running"; // Use gpr_sleep_until rather than this_thread::sleep_until to support // compilers that don't work with this_thread gpr_sleep_until(gpr_time_add( @@ -669,8 +668,8 @@ bool RunQuit( ctx.set_wait_for_ready(true); Status s = stub->QuitWorker(&ctx, phony, &phony); if (!s.ok()) { - gpr_log(GPR_ERROR, "Worker %zu could not be properly quit because %s", i, - s.error_message().c_str()); + LOG(ERROR) << "Worker " << i << " could not be properly quit because " + << s.error_message(); result = false; } } diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc index 87ae89f0f2e..fa43276cf86 100644 --- a/test/cpp/qps/report.cc +++ b/test/cpp/qps/report.cc @@ -20,7 +20,8 @@ #include -#include +#include "absl/log/log.h" + #include #include "src/core/lib/gprpp/crash.h" @@ -79,58 +80,52 @@ void CompositeReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) { } void GprLogReporter::ReportQPS(const ScenarioResult& result) { - gpr_log(GPR_INFO, "QPS: %.1f", result.summary().qps()); + LOG(INFO) << "QPS: " << result.summary().qps(); if (result.summary().failed_requests_per_second() > 0) { - gpr_log(GPR_INFO, "failed requests/second: %.1f", - result.summary().failed_requests_per_second()); - gpr_log(GPR_INFO, "successful requests/second: %.1f", - result.summary().successful_requests_per_second()); + LOG(INFO) << "failed requests/second: " + << result.summary().failed_requests_per_second(); + LOG(INFO) << "successful requests/second: " + << result.summary().successful_requests_per_second(); } } void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result) { - gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", result.summary().qps(), - result.summary().qps_per_server_core()); + LOG(INFO) << "QPS: " << result.summary().qps() << " (" + << result.summary().qps_per_server_core() << "/server core)"; } void GprLogReporter::ReportLatency(const ScenarioResult& result) { - gpr_log(GPR_INFO, - "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us", - result.summary().latency_50() / 1000, - result.summary().latency_90() / 1000, - result.summary().latency_95() / 1000, - result.summary().latency_99() / 1000, - result.summary().latency_999() / 1000); + LOG(INFO) << "Latencies (50/90/95/99/99.9%-ile): " + << result.summary().latency_50() / 1000 << "/" + << result.summary().latency_90() / 1000 << "/" + << result.summary().latency_95() / 1000 << "/" + << result.summary().latency_99() / 1000 << "/" + << result.summary().latency_999() / 1000 << " us"; } void GprLogReporter::ReportTimes(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Server system time: %.2f%%", - result.summary().server_system_time()); - gpr_log(GPR_INFO, "Server user time: %.2f%%", - result.summary().server_user_time()); - gpr_log(GPR_INFO, "Client system time: %.2f%%", - result.summary().client_system_time()); - gpr_log(GPR_INFO, "Client user time: %.2f%%", - result.summary().client_user_time()); + LOG(INFO) << "Server system time: " << result.summary().server_system_time(); + LOG(INFO) << "Server user time: " << result.summary().server_user_time(); + LOG(INFO) << "Client system time: " << result.summary().client_system_time(); + LOG(INFO) << "Client user time: " << result.summary().client_user_time(); } void GprLogReporter::ReportCpuUsage(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Server CPU usage: %.2f%%", - result.summary().server_cpu_usage()); + LOG(INFO) << "Server CPU usage: " << result.summary().server_cpu_usage(); } void GprLogReporter::ReportPollCount(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Client Polls per Request: %.2f", - result.summary().client_polls_per_request()); - gpr_log(GPR_INFO, "Server Polls per Request: %.2f", - result.summary().server_polls_per_request()); + LOG(INFO) << "Client Polls per Request: " + << result.summary().client_polls_per_request(); + LOG(INFO) << "Server Polls per Request: " + << result.summary().server_polls_per_request(); } void GprLogReporter::ReportQueriesPerCpuSec(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Server Queries/CPU-sec: %.2f", - result.summary().server_queries_per_cpu_sec()); - gpr_log(GPR_INFO, "Client Queries/CPU-sec: %.2f", - result.summary().client_queries_per_cpu_sec()); + LOG(INFO) << "Server Queries/CPU-sec: " + << result.summary().server_queries_per_cpu_sec(); + LOG(INFO) << "Client Queries/CPU-sec: " + << result.summary().client_queries_per_cpu_sec(); } void JsonReporter::ReportQPS(const ScenarioResult& result) { @@ -170,14 +165,14 @@ void RpcReporter::ReportQPS(const ScenarioResult& result) { grpc::Status status; Void phony; - gpr_log(GPR_INFO, "RPC reporter sending scenario result to server"); + LOG(INFO) << "RPC reporter sending scenario result to server"; status = stub_->ReportScenario(&context, result, &phony); if (status.ok()) { - gpr_log(GPR_INFO, "RpcReporter report RPC success!"); + LOG(INFO) << "RpcReporter report RPC success!"; } else { - gpr_log(GPR_ERROR, "RpcReporter report RPC: code: %d. message: %s", - status.error_code(), status.error_message().c_str()); + LOG(ERROR) << "RpcReporter report RPC: code: " << status.error_code() + << ". message: " << status.error_message(); } } diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD index ba2f115ee7a..b65ec5c9e86 100644 --- a/test/cpp/server/BUILD +++ b/test/cpp/server/BUILD @@ -28,6 +28,7 @@ grpc_cc_test( deps = [ "//:grpc++_unsecure", "//src/proto/grpc/testing:echo_proto", + "//test/core/event_engine:event_engine_test_utils", "//test/core/test_util:grpc_test_util_base", "//test/core/test_util:grpc_test_util_unsecure", ], diff --git a/test/cpp/server/server_builder_test.cc b/test/cpp/server/server_builder_test.cc index 1765a1d59bf..089f7c38ecf 100644 --- a/test/cpp/server/server_builder_test.cc +++ b/test/cpp/server/server_builder_test.cc @@ -16,14 +16,19 @@ // // +#include + #include +#include #include #include #include #include +#include "src/core/lib/gprpp/notification.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/event_engine/event_engine_test_utils.h" #include "test/core/test_util/port.h" #include "test/core/test_util/test_config.h" @@ -83,6 +88,56 @@ TEST_F(ServerBuilderTest, CreateServerRepeatedPortWithDisallowedReusePort) { nullptr); } +TEST_F(ServerBuilderTest, AddPassiveListener) { + std::unique_ptr passive_listener; + auto server = + ServerBuilder() + .experimental() + .AddPassiveListener(InsecureServerCredentials(), passive_listener) + .BuildAndStart(); + server->Shutdown(); +} + +TEST_F(ServerBuilderTest, PassiveListenerAcceptConnectedFd) { + std::unique_ptr passive_listener; + ServerBuilder builder; + auto cq = builder.AddCompletionQueue(); + // TODO(hork): why is the service necessary? Queue isn't drained otherwise. + auto server = + builder.RegisterService(&g_service) + .experimental() + .AddPassiveListener(InsecureServerCredentials(), passive_listener) + .BuildAndStart(); + ASSERT_NE(server.get(), nullptr); +#ifdef GPR_SUPPORT_CHANNELS_FROM_FD + int fd = socket(AF_INET, SOCK_STREAM, 0); + auto accept_status = passive_listener->AcceptConnectedFd(fd); + ASSERT_TRUE(accept_status.ok()) << accept_status; +#else + int fd = -1; + auto accept_status = passive_listener->AcceptConnectedFd(fd); + ASSERT_FALSE(accept_status.ok()) << accept_status; +#endif + server->Shutdown(); +} + +TEST_F(ServerBuilderTest, PassiveListenerAcceptConnectedEndpoint) { + std::unique_ptr passive_listener; + auto server = + ServerBuilder() + .experimental() + .AddPassiveListener(InsecureServerCredentials(), passive_listener) + .BuildAndStart(); + grpc_core::Notification endpoint_destroyed; + auto success = passive_listener->AcceptConnectedEndpoint( + std::make_unique( + &endpoint_destroyed)); + ASSERT_TRUE(success.ok()) + << "AcceptConnectedEndpoint failure: " << success.ToString(); + endpoint_destroyed.WaitForNotification(); + server->Shutdown(); +} + } // namespace } // namespace grpc diff --git a/tools/bazelify_tests/dockerimage_current_versions.bzl b/tools/bazelify_tests/dockerimage_current_versions.bzl index 423bc0f0237..091fcb09c77 100644 --- a/tools/bazelify_tests/dockerimage_current_versions.bzl +++ b/tools/bazelify_tests/dockerimage_current_versions.bzl @@ -72,7 +72,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = { "tools/dockerfile/grpc_artifact_python_musllinux_1_1_x86.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_artifact_python_musllinux_1_1_x86@sha256:c288f83435186ee675d004ee52c93195a51201bf2b5fe92581584d977a2499a3", "tools/dockerfile/interoptest/grpc_interop_aspnetcore.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_aspnetcore@sha256:8e2e732e78724a8382c340dca72e7653c5f82c251a3110fa2874cc00ba538878", "tools/dockerfile/interoptest/grpc_interop_cxx.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_cxx@sha256:e5a474d33773d52ec6a8abbe2d61ee0c2a9c2b5f48793a5ea3b82c4445becf3f", - "tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:2051ef1cf81c463a65853f6058135f48e52a7572cc2bad57182256b77ef61021", + "tools/dockerfile/interoptest/grpc_interop_dart.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart@sha256:4915a280788126dad029858eb384dbbef2dc18cadccb434df6450dfd7a4929f2", "tools/dockerfile/interoptest/grpc_interop_go.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go@sha256:889e7ff34399a5e16af87940d1eaa239e56da307f7faca3f8f1d28379c2e3df3", "tools/dockerfile/interoptest/grpc_interop_go1.11.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.11@sha256:f2fe3a0a581c687ee4217bf58fd42b18bb1f63d3d006f1b67379ff553b0e23c6", "tools/dockerfile/interoptest/grpc_interop_go1.16.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_go1.16@sha256:3767f47c9d06584c6c07b7ab536e13f3e87550330e6c2652ad288d3a72b0de23", @@ -102,6 +102,7 @@ DOCKERIMAGE_CURRENT_VERSIONS = { "tools/dockerfile/test/cxx_debian11_x86.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_debian11_x86@sha256:3f505ad99e52a4b3337fedb413e883bc8e5c1d9c089299c34002b89e01254d3b", "tools/dockerfile/test/cxx_debian12_openssl309_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_debian12_openssl309_x64@sha256:f75bb715c4f9464526f9affb410f7965a0b8894516d7d98cd89a4e165ae065b7", "tools/dockerfile/test/cxx_gcc_12_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_12_x64@sha256:bbdfe66f27b964f9bfd526646b94a19d904fea52bdb244f32fd4355cc8c4551f", + "tools/dockerfile/test/cxx_gcc_7_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_7_x64@sha256:fb1924844078f48557d6ab57eac1482f80a3cc216406efc3aeaecab671c886d5", "tools/dockerfile/test/cxx_gcc_8_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_8_x64@sha256:989ceb4324a6240940d7185ccb581f8eff656d2c8c36d15fa14e3f57f294c913", "tools/dockerfile/test/php73_zts_debian11_x64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/php73_zts_debian11_x64@sha256:186a96566a9c11adfb198309431086bdb02421121c262a2bf0166e3e9b21fb37", "tools/dockerfile/test/php7_debian11_arm64.current_version": "docker://us-docker.pkg.dev/grpc-testing/testing-images-public/php7_debian11_arm64@sha256:7ee21f253a2ddd255f4f6779cd19818eec6524e78b0bf0a7765339e4aa7347c3", diff --git a/tools/bazelify_tests/test/portability_tests.bzl b/tools/bazelify_tests/test/portability_tests.bzl index bfcc4fbde23..e3328126cbf 100644 --- a/tools/bazelify_tests/test/portability_tests.bzl +++ b/tools/bazelify_tests/test/portability_tests.bzl @@ -53,7 +53,7 @@ def generate_run_tests_portability_tests(name): # C and C++ under different compilers for language in ["c", "c++"]: compiler_configs = [ - ["gcc_7", "", "tools/dockerfile/test/cxx_gcc_8_x64.current_version"], + ["gcc_7", "", "tools/dockerfile/test/cxx_gcc_7_x64.current_version"], ["gcc_12", "--cmake_configure_extra_args=-DCMAKE_CXX_STANDARD=20", "tools/dockerfile/test/cxx_gcc_12_x64.current_version"], ["gcc10.2_openssl102", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl102_x64.current_version"], ["gcc10.2_openssl111", "--cmake_configure_extra_args=-DgRPC_SSL_PROVIDER=package", "tools/dockerfile/test/cxx_debian11_openssl111_x64.current_version"], diff --git a/tools/distrib/check_namespace_qualification.py b/tools/distrib/check_namespace_qualification.py index 6634d8b8830..51ccb71aeb8 100755 --- a/tools/distrib/check_namespace_qualification.py +++ b/tools/distrib/check_namespace_qualification.py @@ -77,6 +77,10 @@ IGNORED_FILES = [ "src/core/lib/gprpp/global_config_env.h", "src/core/lib/profiling/timers.h", "src/core/lib/gprpp/crash.h", + # The grpc_core::Server redundant namespace qualification is required for + # older gcc versions. + "src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/core/server/server.h", ] # find our home diff --git a/tools/distrib/check_redundant_namespace_qualifiers.py b/tools/distrib/check_redundant_namespace_qualifiers.py index 0322332209b..72a5d8b7a3c 100755 --- a/tools/distrib/check_redundant_namespace_qualifiers.py +++ b/tools/distrib/check_redundant_namespace_qualifiers.py @@ -21,6 +21,13 @@ import os import re import sys +IGNORED_FILES = [ + # note: the grpc_core::Server redundant namespace qualification is required + # for older gcc versions. + "src/core/ext/transport/chttp2/server/chttp2_server.h", + "src/core/server/server.h", +] + def find_closing_mustache(contents, initial_depth): """Find the closing mustache for a given number of open mustaches.""" @@ -166,6 +173,8 @@ for config in _CONFIGURATION: for file in files: if file.endswith(".cc") or file.endswith(".h"): path = os.path.join(root, file) + if path in IGNORED_FILES: + continue try: with open(path) as f: contents = f.read() diff --git a/tools/distrib/fix_build_deps.py b/tools/distrib/fix_build_deps.py index 03dbcc9137b..0a114910e3e 100755 --- a/tools/distrib/fix_build_deps.py +++ b/tools/distrib/fix_build_deps.py @@ -64,6 +64,7 @@ EXTERNAL_DEPS = { "absl/functional/bind_front.h": "absl/functional:bind_front", "absl/functional/function_ref.h": "absl/functional:function_ref", "absl/hash/hash.h": "absl/hash", + "absl/log/check.h": "absl/log:check", "absl/memory/memory.h": "absl/memory", "absl/meta/type_traits.h": "absl/meta:type_traits", "absl/numeric/int128.h": "absl/numeric:int128", @@ -543,9 +544,11 @@ def make_library(library): # once EventEngine lands we can clean this up deps = Choices( library, - {"//:grpc_base": ["//:grpc", "//:grpc_unsecure"]} - if library.startswith("//test/") - else {}, + ( + {"//:grpc_base": ["//:grpc", "//:grpc_unsecure"]} + if library.startswith("//test/") + else {} + ), ) external_deps = Choices(None, {}) for hdr in hdrs: diff --git a/tools/dockerfile/interoptest/grpc_interop_dart.current_version b/tools/dockerfile/interoptest/grpc_interop_dart.current_version index 2f4f0413adf..1a055c61de7 100644 --- a/tools/dockerfile/interoptest/grpc_interop_dart.current_version +++ b/tools/dockerfile/interoptest/grpc_interop_dart.current_version @@ -1 +1 @@ -us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:2051ef1cf81c463a65853f6058135f48e52a7572cc2bad57182256b77ef61021 \ No newline at end of file +us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_dart:c795310ab447f964b848b656e083196e0ece2dfc@sha256:4915a280788126dad029858eb384dbbef2dc18cadccb434df6450dfd7a4929f2 \ No newline at end of file diff --git a/tools/dockerfile/test/cxx_gcc_7_x64.current_version b/tools/dockerfile/test/cxx_gcc_7_x64.current_version new file mode 100644 index 00000000000..de82ae1b550 --- /dev/null +++ b/tools/dockerfile/test/cxx_gcc_7_x64.current_version @@ -0,0 +1 @@ +us-docker.pkg.dev/grpc-testing/testing-images-public/cxx_gcc_7_x64:8bc7b7f679857e741188d07a7db7acecf3a9168f@sha256:fb1924844078f48557d6ab57eac1482f80a3cc216406efc3aeaecab671c886d5 \ No newline at end of file diff --git a/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile b/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile new file mode 100644 index 00000000000..a5f56d45055 --- /dev/null +++ b/tools/dockerfile/test/cxx_gcc_7_x64/Dockerfile @@ -0,0 +1,79 @@ +# Copyright 2021 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. + +FROM gcc:7 + +RUN apt-get update && apt-get install -y curl git time wget zip && apt-get clean +#================= +# Setup git to access working directory across docker boundary. +# This avoids the "fatal: detected dubious ownership in repository XYZ" +# git error. + +RUN git config --global --add safe.directory '*' +RUN git config --global protocol.file.allow always + +#==================== +# run_tests.py python dependencies + +# Basic python dependencies to be able to run tools/run_tests python scripts +# These dependencies are not sufficient to build gRPC Python, gRPC Python +# deps are defined elsewhere (e.g. python_deps.include) +RUN apt-get update && apt-get install -y \ + python3 \ + python3-pip \ + python3-setuptools \ + python3-yaml \ + && apt-get clean + +# use pinned version of pip to avoid sudden breakages +RUN python3 -m pip install --upgrade pip==19.3.1 + +# TODO(jtattermusch): currently six is needed for tools/run_tests scripts +# but since our python2 usage is deprecated, we should get rid of it. +RUN python3 -m pip install six==1.16.0 + +# Google Cloud Platform API libraries +# These are needed for uploading test results to BigQuery (e.g. by tools/run_tests scripts) +RUN python3 -m pip install --upgrade google-auth==1.23.0 google-api-python-client==1.12.8 oauth2client==4.1.0 + + +# Some cxx tests depend on the twisted package +RUN python3 -m pip install twisted + +#================= +# Install cmake +# Note that this step should be only used for distributions that have new enough cmake to satisfy gRPC's cmake version requirement. + +RUN apt-get update && apt-get install -y cmake && apt-get clean + +#================= +# Install ccache (use slighly older release of ccache that works older compilers and cmake) + +# Install ccache from source since ccache 3.x packaged with most linux distributions +# does not support Redis backend for caching. +RUN curl -sSL -o ccache.tar.gz https://github.com/ccache/ccache/releases/download/v4.5.1/ccache-4.5.1.tar.gz \ + && tar -zxf ccache.tar.gz \ + && cd ccache-4.5.1 \ + && mkdir build && cd build \ + && cmake -DCMAKE_BUILD_TYPE=Release -DZSTD_FROM_INTERNET=ON -DHIREDIS_FROM_INTERNET=ON .. \ + && make -j4 && make install \ + && cd ../.. \ + && rm -rf ccache-4.5.1 ccache.tar.gz + + +RUN mkdir /var/local/jenkins + + +# Define the default command. +CMD ["bash"] diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 6a50207e16d..299c480565d 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -928,6 +928,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ @@ -1040,6 +1041,7 @@ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/impl/status.h \ include/grpcpp/impl/sync.h \ +include/grpcpp/passive_listener.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/audit_logging.h \ include/grpcpp/security/auth_context.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8dd3bb12622..649e1eb576a 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -928,6 +928,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ @@ -1040,6 +1041,7 @@ include/grpcpp/impl/server_initializer.h \ include/grpcpp/impl/service_type.h \ include/grpcpp/impl/status.h \ include/grpcpp/impl/sync.h \ +include/grpcpp/passive_listener.h \ include/grpcpp/resource_quota.h \ include/grpcpp/security/audit_logging.h \ include/grpcpp/security/auth_context.h \ @@ -2748,6 +2750,7 @@ src/core/lib/transport/bdp_estimator.cc \ src/core/lib/transport/bdp_estimator.h \ src/core/lib/transport/call_arena_allocator.cc \ src/core/lib/transport/call_arena_allocator.h \ +src/core/lib/transport/call_destination.h \ src/core/lib/transport/call_filters.cc \ src/core/lib/transport/call_filters.h \ src/core/lib/transport/call_final_info.cc \ @@ -2760,6 +2763,8 @@ src/core/lib/transport/custom_metadata.h \ src/core/lib/transport/error_utils.cc \ src/core/lib/transport/error_utils.h \ src/core/lib/transport/http2_errors.h \ +src/core/lib/transport/interception_chain.cc \ +src/core/lib/transport/interception_chain.h \ src/core/lib/transport/message.cc \ src/core/lib/transport/message.h \ src/core/lib/transport/metadata.cc \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 592e357f54f..20b553dadfe 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -861,6 +861,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 74fd1131517..d3a4f44a588 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -861,6 +861,7 @@ include/grpc/impl/grpc_types.h \ include/grpc/impl/propagation_bits.h \ include/grpc/impl/slice_type.h \ include/grpc/load_reporting.h \ +include/grpc/passive_listener.h \ include/grpc/slice.h \ include/grpc/slice_buffer.h \ include/grpc/status.h \ @@ -2526,6 +2527,7 @@ src/core/lib/transport/bdp_estimator.cc \ src/core/lib/transport/bdp_estimator.h \ src/core/lib/transport/call_arena_allocator.cc \ src/core/lib/transport/call_arena_allocator.h \ +src/core/lib/transport/call_destination.h \ src/core/lib/transport/call_filters.cc \ src/core/lib/transport/call_filters.h \ src/core/lib/transport/call_final_info.cc \ @@ -2538,6 +2540,8 @@ src/core/lib/transport/custom_metadata.h \ src/core/lib/transport/error_utils.cc \ src/core/lib/transport/error_utils.h \ src/core/lib/transport/http2_errors.h \ +src/core/lib/transport/interception_chain.cc \ +src/core/lib/transport/interception_chain.h \ src/core/lib/transport/message.cc \ src/core/lib/transport/message.h \ src/core/lib/transport/metadata.cc \ diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 61b98ca9bd1..a733817a370 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -2969,6 +2969,30 @@ ], "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": "dump_args_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, { "args": [], "benchmark": false, diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py index 7804dd0fe52..806f3c806b6 100755 --- a/tools/run_tests/sanity/core_banned_functions.py +++ b/tools/run_tests/sanity/core_banned_functions.py @@ -82,8 +82,8 @@ BANNED_EXCEPT = { "src/core/load_balancing/rls/rls.cc", "src/core/resolver/google_c2p/google_c2p_resolver.cc", ], - # use 'grpc_core::Crash' instead - "GPR_ASSERT(false": [], + # use 'absl CHECK' instead + "GPR_ASSERT": [], # Use `std::exchange()` instead. "absl::exchange": [], # Use `std::make_unique()` instead.