diff --git a/Makefile b/Makefile
index bf9a5e29142..a6c76a6a15d 100644
--- a/Makefile
+++ b/Makefile
@@ -1757,6 +1757,7 @@ h2_uds+poll_trailing_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_traili
connection_prefix_bad_client_test: $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
headers_bad_client_test: $(BINDIR)/$(CONFIG)/headers_bad_client_test
initial_settings_frame_bad_client_test: $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
+unknown_frame_bad_client_test: $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
run_dep_checks:
$(OPENSSL_ALPN_CHECK_CMD) || true
@@ -1881,7 +1882,7 @@ endif
buildtests: buildtests_c buildtests_cxx buildtests_zookeeper
-buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/compression_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/endpoint_pair_test $(BINDIR)/$(CONFIG)/fd_conservation_posix_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_avl_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_cpu_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_auth_context_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_args_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test $(BINDIR)/$(CONFIG)/grpc_security_connector_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/init_test $(BINDIR)/$(CONFIG)/invalid_call_argument_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/lb_policies_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/multiple_server_queues_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/set_initial_connect_string_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/timer_heap_test $(BINDIR)/$(CONFIG)/timer_list_test $(BINDIR)/$(CONFIG)/timers_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/udp_server_test $(BINDIR)/$(CONFIG)/uri_parser_test $(BINDIR)/$(CONFIG)/workqueue_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_call_creds_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_compress_channel_ping_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_test $(BINDIR)/$(CONFIG)/h2_compress_payload_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_fakesec_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_call_creds_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_fakesec_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_fakesec_channel_ping_test $(BINDIR)/$(CONFIG)/h2_fakesec_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_default_host_test $(BINDIR)/$(CONFIG)/h2_fakesec_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_fakesec_empty_batch_test $(BINDIR)/$(CONFIG)/h2_fakesec_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_fakesec_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test $(BINDIR)/$(CONFIG)/h2_fakesec_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_large_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_message_length_test $(BINDIR)/$(CONFIG)/h2_fakesec_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_fakesec_no_op_test $(BINDIR)/$(CONFIG)/h2_fakesec_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_fakesec_registered_call_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full_call_creds_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full_channel_ping_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full_default_host_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full_hpack_size_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full_metadata_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full_no_op_test $(BINDIR)/$(CONFIG)/h2_full_payload_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_ping_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_oauth2_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_call_creds_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_oauth2_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_oauth2_channel_ping_test $(BINDIR)/$(CONFIG)/h2_oauth2_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_default_host_test $(BINDIR)/$(CONFIG)/h2_oauth2_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_oauth2_empty_batch_test $(BINDIR)/$(CONFIG)/h2_oauth2_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_oauth2_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test $(BINDIR)/$(CONFIG)/h2_oauth2_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_large_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_message_length_test $(BINDIR)/$(CONFIG)/h2_oauth2_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_oauth2_no_op_test $(BINDIR)/$(CONFIG)/h2_oauth2_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_oauth2_registered_call_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl_channel_ping_test $(BINDIR)/$(CONFIG)/h2_ssl_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test $(BINDIR)/$(CONFIG)/h2_ssl_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_channel_ping_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_call_creds_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds_channel_ping_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_test $(BINDIR)/$(CONFIG)/h2_uds_payload_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_ping_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test $(BINDIR)/$(CONFIG)/headers_bad_client_test $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
+buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/compression_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/endpoint_pair_test $(BINDIR)/$(CONFIG)/fd_conservation_posix_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_avl_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_cpu_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_auth_context_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_args_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test $(BINDIR)/$(CONFIG)/grpc_security_connector_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/init_test $(BINDIR)/$(CONFIG)/invalid_call_argument_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/lb_policies_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/multiple_server_queues_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/set_initial_connect_string_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/timer_heap_test $(BINDIR)/$(CONFIG)/timer_list_test $(BINDIR)/$(CONFIG)/timers_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/udp_server_test $(BINDIR)/$(CONFIG)/uri_parser_test $(BINDIR)/$(CONFIG)/workqueue_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_call_creds_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_compress_channel_ping_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_test $(BINDIR)/$(CONFIG)/h2_compress_payload_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_fakesec_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_call_creds_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_fakesec_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_fakesec_channel_ping_test $(BINDIR)/$(CONFIG)/h2_fakesec_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_default_host_test $(BINDIR)/$(CONFIG)/h2_fakesec_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_fakesec_empty_batch_test $(BINDIR)/$(CONFIG)/h2_fakesec_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_fakesec_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test $(BINDIR)/$(CONFIG)/h2_fakesec_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_large_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_message_length_test $(BINDIR)/$(CONFIG)/h2_fakesec_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_fakesec_no_op_test $(BINDIR)/$(CONFIG)/h2_fakesec_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_fakesec_registered_call_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full_call_creds_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full_channel_ping_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full_default_host_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full_hpack_size_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full_metadata_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full_no_op_test $(BINDIR)/$(CONFIG)/h2_full_payload_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_ping_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_oauth2_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_call_creds_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_oauth2_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_oauth2_channel_ping_test $(BINDIR)/$(CONFIG)/h2_oauth2_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_default_host_test $(BINDIR)/$(CONFIG)/h2_oauth2_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_oauth2_empty_batch_test $(BINDIR)/$(CONFIG)/h2_oauth2_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_oauth2_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test $(BINDIR)/$(CONFIG)/h2_oauth2_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_large_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_message_length_test $(BINDIR)/$(CONFIG)/h2_oauth2_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_oauth2_no_op_test $(BINDIR)/$(CONFIG)/h2_oauth2_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_oauth2_registered_call_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl_channel_ping_test $(BINDIR)/$(CONFIG)/h2_ssl_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test $(BINDIR)/$(CONFIG)/h2_ssl_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_channel_ping_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_call_creds_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds_channel_ping_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_test $(BINDIR)/$(CONFIG)/h2_uds_payload_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_ping_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_ping_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test $(BINDIR)/$(CONFIG)/headers_bad_client_test $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
buildtests_cxx: buildtests_zookeeper privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test $(BINDIR)/$(CONFIG)/auth_property_iterator_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/client_crash_test $(BINDIR)/$(CONFIG)/client_crash_test_server $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test $(BINDIR)/$(CONFIG)/cxx_slice_test $(BINDIR)/$(CONFIG)/cxx_string_ref_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/metrics_client $(BINDIR)/$(CONFIG)/mock_test $(BINDIR)/$(CONFIG)/qps_interarrival_test $(BINDIR)/$(CONFIG)/qps_openloop_test $(BINDIR)/$(CONFIG)/qps_test $(BINDIR)/$(CONFIG)/reconnect_interop_client $(BINDIR)/$(CONFIG)/reconnect_interop_server $(BINDIR)/$(CONFIG)/secure_auth_context_test $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/server_crash_test $(BINDIR)/$(CONFIG)/server_crash_test_client $(BINDIR)/$(CONFIG)/shutdown_test $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/streaming_throughput_test $(BINDIR)/$(CONFIG)/stress_test $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/thread_stress_test
@@ -3747,6 +3748,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/headers_bad_client_test || ( echo test headers_bad_client_test failed ; exit 1 )
$(E) "[RUN] Testing initial_settings_frame_bad_client_test"
$(Q) $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test || ( echo test initial_settings_frame_bad_client_test failed ; exit 1 )
+ $(E) "[RUN] Testing unknown_frame_bad_client_test"
+ $(Q) $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test || ( echo test unknown_frame_bad_client_test failed ; exit 1 )
flaky_test_c: buildtests_c
@@ -24448,6 +24451,23 @@ ifneq ($(NO_DEPS),true)
endif
+UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC = \
+ test/core/bad_client/tests/unknown_frame.c \
+
+UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(UNKNOWN_FRAME_BAD_CLIENT_TEST_SRC))))
+$(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
+
+$(OBJDIR)/$(CONFIG)/test/core/bad_client/tests/unknown_frame.o: $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+deps_unknown_frame_bad_client_test: $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(UNKNOWN_FRAME_BAD_CLIENT_TEST_OBJS:.o=.dep)
+endif
+
+
diff --git a/package.json b/package.json
index 9517c59aced..f39dfc4c7cc 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,8 @@
"minimist": "^1.1.0",
"mocha": "~1.21.0",
"mocha-jenkins-reporter": "^0.1.9",
- "mustache": "^2.0.0"
+ "mustache": "^2.0.0",
+ "poisson-process": "^0.2.1"
},
"engines": {
"node": ">=0.10.13"
diff --git a/src/core/census/context.h b/src/core/census/context.h
index d9907d4da75..e45409a6b83 100644
--- a/src/core/census/context.h
+++ b/src/core/census/context.h
@@ -39,11 +39,7 @@
/* census_context is the in-memory representation of information needed to
* maintain tracing, RPC statistics and resource usage information. */
struct census_context {
- gpr_uint64 op_id; /* Operation identifier - unique per-context */
- gpr_uint64 trace_id; /* Globally unique trace identifier */
- /* TODO(aveitch) Add census tags:
- const census_tag_set *tags;
- */
+ census_tag_set *tags; /* Opaque data structure for census tags. */
};
#endif /* GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H */
diff --git a/src/core/support/slice.c b/src/core/support/slice.c
index 5b091f17b0f..9f0ded4932b 100644
--- a/src/core/support/slice.c
+++ b/src/core/support/slice.c
@@ -341,10 +341,3 @@ int gpr_slice_str_cmp(gpr_slice a, const char *b) {
if (d != 0) return d;
return memcmp(GPR_SLICE_START_PTR(a), b, b_length);
}
-
-char *gpr_slice_to_cstring(gpr_slice slice) {
- char *result = gpr_malloc(GPR_SLICE_LENGTH(slice) + 1);
- memcpy(result, GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice));
- result[GPR_SLICE_LENGTH(slice)] = '\0';
- return result;
-}
diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c
index e07fbb2cc75..38fa990758a 100644
--- a/src/core/transport/chttp2/frame_data.c
+++ b/src/core/transport/chttp2/frame_data.c
@@ -118,7 +118,7 @@ void grpc_chttp2_encode_data(gpr_uint32 id, gpr_slice_buffer *inbuf,
hdr = gpr_slice_malloc(9);
p = GPR_SLICE_START_PTR(hdr);
- GPR_ASSERT(write_bytes < 16777316);
+ GPR_ASSERT(write_bytes < (1<<24));
*p++ = (gpr_uint8)(write_bytes >> 16);
*p++ = (gpr_uint8)(write_bytes >> 8);
*p++ = (gpr_uint8)(write_bytes);
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
index e5453000ec0..30f0d469e38 100644
--- a/src/core/transport/chttp2/hpack_parser.c
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -1418,15 +1418,19 @@ grpc_chttp2_parse_error grpc_chttp2_header_parser_parse(
GPR_TIMER_END("grpc_chttp2_hpack_parser_parse", 0);
return GRPC_CHTTP2_CONNECTION_ERROR;
}
- if (parser->is_boundary) {
- stream_parsing
- ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1;
- stream_parsing->header_frames_received++;
- grpc_chttp2_list_add_parsing_seen_stream(transport_parsing,
- stream_parsing);
- }
- if (parser->is_eof) {
- stream_parsing->received_close = 1;
+ /* need to check for null stream: this can occur if we receive an invalid
+ stream id on a header */
+ if (stream_parsing != NULL) {
+ if (parser->is_boundary) {
+ stream_parsing
+ ->got_metadata_on_parse[stream_parsing->header_frames_received] = 1;
+ stream_parsing->header_frames_received++;
+ grpc_chttp2_list_add_parsing_seen_stream(transport_parsing,
+ stream_parsing);
+ }
+ if (parser->is_eof) {
+ stream_parsing->received_close = 1;
+ }
}
parser->on_header = on_header_not_set;
parser->on_header_user_data = NULL;
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
index 55462e02fd5..53b2bb78c4c 100644
--- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj
+++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
@@ -66,6 +66,5 @@
-
-
\ No newline at end of file
+
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
index 8fce5d39aab..4e775a7a0c9 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
@@ -65,7 +65,6 @@
-
@@ -81,4 +80,4 @@
-->
-
\ No newline at end of file
+
diff --git a/src/csharp/Grpc.HealthCheck/proto/health.proto b/src/csharp/Grpc.HealthCheck/proto/health.proto
deleted file mode 100644
index 01aa3fcf577..00000000000
--- a/src/csharp/Grpc.HealthCheck/proto/health.proto
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2015, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// TODO(jtattermusch): switch to proto3 once C# supports that.
-syntax = "proto3";
-
-package grpc.health.v1alpha;
-option csharp_namespace = "Grpc.Health.V1Alpha";
-
-message HealthCheckRequest {
- string host = 1;
- string service = 2;
-}
-
-message HealthCheckResponse {
- enum ServingStatus {
- UNKNOWN = 0;
- SERVING = 1;
- NOT_SERVING = 2;
- }
- ServingStatus status = 1;
-}
-
-service Health {
- rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
-}
\ No newline at end of file
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index 92348d13942..4dbd9c33085 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -30,19 +30,19 @@
# Regenerates gRPC service stubs from proto files.
set +e
-cd $(dirname $0)
+cd $(dirname $0)/../..
-PROTOC=../../bins/opt/protobuf/protoc
-PLUGIN=protoc-gen-grpc=../../bins/opt/grpc_csharp_plugin
-EXAMPLES_DIR=Grpc.Examples
-TESTING_DIR=Grpc.IntegrationTesting
-HEALTHCHECK_DIR=Grpc.HealthCheck
+PROTOC=bins/opt/protobuf/protoc
+PLUGIN=protoc-gen-grpc=bins/opt/grpc_csharp_plugin
+EXAMPLES_DIR=src/csharp/Grpc.Examples
+HEALTHCHECK_DIR=src/csharp/Grpc.HealthCheck
+TESTING_DIR=src/csharp/Grpc.IntegrationTesting
$PROTOC --plugin=$PLUGIN --csharp_out=$EXAMPLES_DIR --grpc_out=$EXAMPLES_DIR \
- -I $EXAMPLES_DIR/proto $EXAMPLES_DIR/proto/math.proto
-
-$PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
- -I ../.. ../../test/proto/*.proto ../../test/proto/benchmarks/*.proto
+ -I src/proto/math src/proto/math/math.proto
$PROTOC --plugin=$PLUGIN --csharp_out=$HEALTHCHECK_DIR --grpc_out=$HEALTHCHECK_DIR \
- -I $HEALTHCHECK_DIR/proto $HEALTHCHECK_DIR/proto/health.proto
+ -I src/proto/grpc/health/v1alpha src/proto/grpc/health/v1alpha/health.proto
+
+$PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
+ -I . test/proto/{empty,messages,test}.proto test/proto/benchmarks/*.proto
diff --git a/src/node/health_check/health.js b/src/node/health_check/health.js
index 84d7e0568e5..1a2c0366875 100644
--- a/src/node/health_check/health.js
+++ b/src/node/health_check/health.js
@@ -37,7 +37,8 @@ var grpc = require('../');
var _ = require('lodash');
-var health_proto = grpc.load(__dirname + '/health.proto');
+var health_proto = grpc.load(__dirname +
+ '/../../proto/grpc/health/v1alpha/health.proto');
var HealthClient = health_proto.grpc.health.v1alpha.Health;
diff --git a/src/node/health_check/health.proto b/src/node/health_check/health.proto
deleted file mode 100644
index 57f4aaa9c08..00000000000
--- a/src/node/health_check/health.proto
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2015, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package grpc.health.v1alpha;
-
-message HealthCheckRequest {
- string service = 1;
-}
-
-message HealthCheckResponse {
- enum ServingStatus {
- UNKNOWN = 0;
- SERVING = 1;
- NOT_SERVING = 2;
- }
- ServingStatus status = 1;
-}
-
-service Health {
- rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
-}
diff --git a/src/node/performance/benchmark_client.js b/src/node/performance/benchmark_client.js
new file mode 100644
index 00000000000..d97bdbbcaf7
--- /dev/null
+++ b/src/node/performance/benchmark_client.js
@@ -0,0 +1,336 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * Benchmark client module
+ * @module
+ */
+
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+var util = require('util');
+var EventEmitter = require('events');
+var _ = require('lodash');
+var PoissonProcess = require('poisson-process');
+var Histogram = require('./histogram');
+var grpc = require('../../../');
+var serviceProto = grpc.load({
+ root: __dirname + '/../../..',
+ file: 'test/proto/benchmarks/services.proto'}).grpc.testing;
+
+/**
+ * Create a buffer filled with size zeroes
+ * @param {number} size The length of the buffer
+ * @return {Buffer} The new buffer
+ */
+function zeroBuffer(size) {
+ var zeros = new Buffer(size);
+ zeros.fill(0);
+ return zeros;
+}
+
+/**
+ * Convert a time difference, as returned by process.hrtime, to a number of
+ * nanoseconds.
+ * @param {Array.} time_diff The time diff, represented as
+ * [seconds, nanoseconds]
+ * @return {number} The total number of nanoseconds
+ */
+function timeDiffToNanos(time_diff) {
+ return time_diff[0] * 1e9 + time_diff[1];
+}
+
+/**
+ * The BenchmarkClient class. Opens channels to servers and makes RPCs based on
+ * parameters from the driver, and records statistics about those RPCs.
+ * @param {Array.} server_targets List of servers to connect to
+ * @param {number} channels The total number of channels to open
+ * @param {Object} histogram_params Options for setting up the histogram
+ * @param {Object=} security_params Options for TLS setup. If absent, don't use
+ * TLS
+ */
+function BenchmarkClient(server_targets, channels, histogram_params,
+ security_params) {
+ var options = {};
+ var creds;
+ if (security_params) {
+ var ca_path;
+ if (security_params.use_test_ca) {
+ ca_path = path.join(__dirname, '../test/data/ca.pem');
+ var ca_data = fs.readFileSync(ca_path);
+ creds = grpc.credentials.createSsl(ca_data);
+ } else {
+ creds = grpc.credentials.createSsl();
+ }
+ if (security_params.server_host_override) {
+ var host_override = security_params.server_host_override;
+ options['grpc.ssl_target_name_override'] = host_override;
+ options['grpc.default_authority'] = host_override;
+ }
+ } else {
+ creds = grpc.credentials.createInsecure();
+ }
+
+ this.clients = [];
+
+ for (var i = 0; i < channels; i++) {
+ this.clients[i] = new serviceProto.BenchmarkService(
+ server_targets[i % server_targets.length], creds, options);
+ }
+
+ this.histogram = new Histogram(histogram_params.resolution,
+ histogram_params.max_possible);
+
+ this.running = false;
+
+ this.pending_calls = 0;
+};
+
+util.inherits(BenchmarkClient, EventEmitter);
+
+/**
+ * Start a closed-loop test. For each channel, start
+ * outstanding_rpcs_per_channel RPCs. Then, whenever an RPC finishes, start
+ * another one.
+ * @param {number} outstanding_rpcs_per_channel Number of RPCs to start per
+ * channel
+ * @param {string} rpc_type Which method to call. Should be 'UNARY' or
+ * 'STREAMING'
+ * @param {number} req_size The size of the payload to send with each request
+ * @param {number} resp_size The size of payload to request be sent in responses
+ */
+BenchmarkClient.prototype.startClosedLoop = function(
+ outstanding_rpcs_per_channel, rpc_type, req_size, resp_size) {
+ var self = this;
+
+ self.running = true;
+
+ self.last_wall_time = process.hrtime();
+
+ var makeCall;
+
+ var argument = {
+ response_size: resp_size,
+ payload: {
+ body: zeroBuffer(req_size)
+ }
+ };
+
+ if (rpc_type == 'UNARY') {
+ makeCall = function(client) {
+ if (self.running) {
+ self.pending_calls++;
+ var start_time = process.hrtime();
+ client.unaryCall(argument, function(error, response) {
+ if (error) {
+ self.emit('error', new Error('Client error: ' + error.message));
+ self.running = false;
+ return;
+ }
+ var time_diff = process.hrtime(start_time);
+ self.histogram.add(timeDiffToNanos(time_diff));
+ makeCall(client);
+ self.pending_calls--;
+ if ((!self.running) && self.pending_calls == 0) {
+ self.emit('finished');
+ }
+ });
+ }
+ };
+ } else {
+ makeCall = function(client) {
+ if (self.running) {
+ self.pending_calls++;
+ var start_time = process.hrtime();
+ var call = client.streamingCall();
+ call.write(argument);
+ call.on('data', function() {
+ });
+ call.on('end', function() {
+ var time_diff = process.hrtime(start_time);
+ self.histogram.add(timeDiffToNanos(time_diff));
+ makeCall(client);
+ self.pending_calls--;
+ if ((!self.running) && self.pending_calls == 0) {
+ self.emit('finished');
+ }
+ });
+ call.on('error', function(error) {
+ self.emit('error', new Error('Client error: ' + error.message));
+ self.running = false;
+ });
+ }
+ };
+ }
+
+ _.each(self.clients, function(client) {
+ _.times(outstanding_rpcs_per_channel, function() {
+ makeCall(client);
+ });
+ });
+};
+
+/**
+ * Start a poisson test. For each channel, this initiates a number of Poisson
+ * processes equal to outstanding_rpcs_per_channel, where each Poisson process
+ * has the load parameter offered_load.
+ * @param {number} outstanding_rpcs_per_channel Number of RPCs to start per
+ * channel
+ * @param {string} rpc_type Which method to call. Should be 'UNARY' or
+ * 'STREAMING'
+ * @param {number} req_size The size of the payload to send with each request
+ * @param {number} resp_size The size of payload to request be sent in responses
+ * @param {number} offered_load The load parameter for the Poisson process
+ */
+BenchmarkClient.prototype.startPoisson = function(
+ outstanding_rpcs_per_channel, rpc_type, req_size, resp_size, offered_load) {
+ var self = this;
+
+ self.running = true;
+
+ self.last_wall_time = process.hrtime();
+
+ var makeCall;
+
+ var argument = {
+ response_size: resp_size,
+ payload: {
+ body: zeroBuffer(req_size)
+ }
+ };
+
+ if (rpc_type == 'UNARY') {
+ makeCall = function(client, poisson) {
+ if (self.running) {
+ self.pending_calls++;
+ var start_time = process.hrtime();
+ client.unaryCall(argument, function(error, response) {
+ if (error) {
+ self.emit('error', new Error('Client error: ' + error.message));
+ self.running = false;
+ return;
+ }
+ var time_diff = process.hrtime(start_time);
+ self.histogram.add(timeDiffToNanos(time_diff));
+ self.pending_calls--;
+ if ((!self.running) && self.pending_calls == 0) {
+ self.emit('finished');
+ }
+ });
+ } else {
+ poisson.stop();
+ }
+ };
+ } else {
+ makeCall = function(client, poisson) {
+ if (self.running) {
+ self.pending_calls++;
+ var start_time = process.hrtime();
+ var call = client.streamingCall();
+ call.write(argument);
+ call.on('data', function() {
+ });
+ call.on('end', function() {
+ var time_diff = process.hrtime(start_time);
+ self.histogram.add(timeDiffToNanos(time_diff));
+ self.pending_calls--;
+ if ((!self.running) && self.pending_calls == 0) {
+ self.emit('finished');
+ }
+ });
+ call.on('error', function(error) {
+ self.emit('error', new Error('Client error: ' + error.message));
+ self.running = false;
+ });
+ } else {
+ poisson.stop();
+ }
+ };
+ }
+
+ var averageIntervalMs = (1 / offered_load) * 1000;
+
+ _.each(self.clients, function(client) {
+ _.times(outstanding_rpcs_per_channel, function() {
+ var p = PoissonProcess.create(averageIntervalMs, function() {
+ makeCall(client, p);
+ });
+ p.start();
+ });
+ });
+};
+
+/**
+ * Return curent statistics for the client. If reset is set, restart
+ * statistic collection.
+ * @param {boolean} reset Indicates that statistics should be reset
+ * @return {object} Client statistics
+ */
+BenchmarkClient.prototype.mark = function(reset) {
+ var wall_time_diff = process.hrtime(this.last_wall_time);
+ var histogram = this.histogram;
+ if (reset) {
+ this.last_wall_time = process.hrtime();
+ this.histogram = new Histogram(histogram.resolution,
+ histogram.max_possible);
+ }
+
+ return {
+ latencies: {
+ bucket: histogram.getContents(),
+ min_seen: histogram.minimum(),
+ max_seen: histogram.maximum(),
+ sum: histogram.getSum(),
+ sum_of_squares: histogram.sumOfSquares(),
+ count: histogram.getCount()
+ },
+ time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
+ // Not sure how to measure these values
+ time_user: 0,
+ time_system: 0
+ };
+};
+
+/**
+ * Stop the clients.
+ * @param {function} callback Called when the clients have finished shutting
+ * down
+ */
+BenchmarkClient.prototype.stop = function(callback) {
+ this.running = false;
+ this.on('finished', callback);
+};
+
+module.exports = BenchmarkClient;
diff --git a/src/node/performance/benchmark_server.js b/src/node/performance/benchmark_server.js
new file mode 100644
index 00000000000..ac96fc5edb3
--- /dev/null
+++ b/src/node/performance/benchmark_server.js
@@ -0,0 +1,162 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * Benchmark server module
+ * @module
+ */
+
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+
+var grpc = require('../../../');
+var serviceProto = grpc.load({
+ root: __dirname + '/../../..',
+ file: 'test/proto/benchmarks/services.proto'}).grpc.testing;
+
+/**
+ * Create a buffer filled with size zeroes
+ * @param {number} size The length of the buffer
+ * @return {Buffer} The new buffer
+ */
+function zeroBuffer(size) {
+ var zeros = new Buffer(size);
+ zeros.fill(0);
+ return zeros;
+}
+
+/**
+ * Handler for the unary benchmark method. Simply responds with a payload
+ * containing the requested number of zero bytes.
+ * @param {Call} call The call object to be handled
+ * @param {function} callback The callback to call with the response
+ */
+function unaryCall(call, callback) {
+ var req = call.request;
+ var payload = {body: zeroBuffer(req.response_size)};
+ callback(null, {payload: payload});
+}
+
+/**
+ * Handler for the streaming benchmark method. Simply responds to each request
+ * with a payload containing the requested number of zero bytes.
+ * @param {Call} call The call object to be handled
+ */
+function streamingCall(call) {
+ call.on('data', function(value) {
+ var payload = {body: zeroBuffer(value.repsonse_size)};
+ call.write({payload: payload});
+ });
+ call.on('end', function() {
+ call.end();
+ });
+}
+
+/**
+ * BenchmarkServer class. Constructed based on parameters from the driver and
+ * stores statistics.
+ * @param {string} host The host to serve on
+ * @param {number} port The port to listen to
+ * @param {tls} Indicates whether TLS should be used
+ */
+function BenchmarkServer(host, port, tls) {
+ var server_creds;
+ var host_override;
+ if (tls) {
+ var key_path = path.join(__dirname, '../test/data/server1.key');
+ var pem_path = path.join(__dirname, '../test/data/server1.pem');
+
+ var key_data = fs.readFileSync(key_path);
+ var pem_data = fs.readFileSync(pem_path);
+ server_creds = grpc.ServerCredentials.createSsl(null,
+ [{private_key: key_data,
+ cert_chain: pem_data}]);
+ } else {
+ server_creds = grpc.ServerCredentials.createInsecure();
+ }
+
+ var server = new grpc.Server();
+ this.port = server.bind(host + ':' + port, server_creds);
+ server.addProtoService(serviceProto.BenchmarkService.service, {
+ unaryCall: unaryCall,
+ streamingCall: streamingCall
+ });
+ this.server = server;
+}
+
+/**
+ * Start the benchmark server.
+ */
+BenchmarkServer.prototype.start = function() {
+ this.server.start();
+ this.last_wall_time = process.hrtime();
+};
+
+/**
+ * Return the port number that the server is bound to.
+ * @return {Number} The port number
+ */
+BenchmarkServer.prototype.getPort = function() {
+ return this.port;
+};
+
+/**
+ * Return current statistics for the server. If reset is set, restart
+ * statistic collection.
+ * @param {boolean} reset Indicates that statistics should be reset
+ * @return {object} Server statistics
+ */
+BenchmarkServer.prototype.mark = function(reset) {
+ var wall_time_diff = process.hrtime(this.last_wall_time);
+ if (reset) {
+ this.last_wall_time = process.hrtime();
+ }
+ return {
+ time_elapsed: wall_time_diff[0] + wall_time_diff[1] / 1e9,
+ // Not sure how to measure these values
+ time_user: 0,
+ time_system: 0
+ };
+};
+
+/**
+ * Stop the server.
+ * @param {function} callback Called when the server has finished shutting down
+ */
+BenchmarkServer.prototype.stop = function(callback) {
+ this.server.tryShutdown(callback);
+};
+
+module.exports = BenchmarkServer;
diff --git a/src/node/performance/histogram.js b/src/node/performance/histogram.js
new file mode 100644
index 00000000000..204d7d47daf
--- /dev/null
+++ b/src/node/performance/histogram.js
@@ -0,0 +1,180 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * Histogram module. Exports the Histogram class
+ * @module
+ */
+
+'use strict';
+
+/**
+ * Histogram class. Collects data and exposes a histogram and other statistics.
+ * This data structure is taken directly from src/core/support/histogram.c, but
+ * pared down to the statistics needed for client stats in
+ * test/proto/benchmarks/stats.proto.
+ * @constructor
+ * @param {number} resolution The histogram's bucket resolution. Must be positive
+ * @param {number} max_possible The maximum allowed value. Must be greater than 1
+ */
+function Histogram(resolution, max_possible) {
+ this.resolution = resolution;
+ this.max_possible = max_possible;
+
+ this.sum = 0;
+ this.sum_of_squares = 0;
+ this.multiplier = 1 + resolution;
+ this.count = 0;
+ this.min_seen = max_possible;
+ this.max_seen = 0;
+ this.buckets = [];
+ for (var i = 0; i < this.bucketFor(max_possible) + 1; i++) {
+ this.buckets[i] = 0;
+ }
+}
+
+/**
+ * Get the bucket index for a given value.
+ * @param {number} value The value to check
+ * @return {number} The bucket index
+ */
+Histogram.prototype.bucketFor = function(value) {
+ return Math.floor(Math.log(value) / Math.log(this.multiplier));
+};
+
+/**
+ * Get the minimum value for a given bucket index
+ * @param {number} The bucket index to check
+ * @return {number} The minimum value for that bucket
+ */
+Histogram.prototype.bucketStart = function(index) {
+ return Math.pow(this.multiplier, index);
+};
+
+/**
+ * Add a value to the histogram. This updates all statistics with the new
+ * value. Those statistics should not be modified except with this function
+ * @param {number} value The value to add
+ */
+Histogram.prototype.add = function(value) {
+ // Ensure value is a number
+ value = +value;
+ this.sum += value;
+ this.sum_of_squares += value * value;
+ this.count++;
+ if (value < this.min_seen) {
+ this.min_seen = value;
+ }
+ if (value > this.max_seen) {
+ this.max_seen = value;
+ }
+ this.buckets[this.bucketFor(value)]++;
+};
+
+/**
+ * Get the mean of all added values
+ * @return {number} The mean
+ */
+Histogram.prototype.mean = function() {
+ return this.sum / this.count;
+};
+
+/**
+ * Get the variance of all added values. Used to calulate the standard deviation
+ * @return {number} The variance
+ */
+Histogram.prototype.variance = function() {
+ if (this.count == 0) {
+ return 0;
+ }
+ return (this.sum_of_squares * this.count - this.sum * this.sum) /
+ (this.count * this.count);
+};
+
+/**
+ * Get the standard deviation of all added values
+ * @return {number} The standard deviation
+ */
+Histogram.prototype.stddev = function() {
+ return Math.sqrt(this.variance);
+};
+
+/**
+ * Get the maximum among all added values
+ * @return {number} The maximum
+ */
+Histogram.prototype.maximum = function() {
+ return this.max_seen;
+};
+
+/**
+ * Get the minimum among all added values
+ * @return {number} The minimum
+ */
+Histogram.prototype.minimum = function() {
+ return this.min_seen;
+};
+
+/**
+ * Get the number of all added values
+ * @return {number} The count
+ */
+Histogram.prototype.getCount = function() {
+ return this.count;
+};
+
+/**
+ * Get the sum of all added values
+ * @return {number} The sum
+ */
+Histogram.prototype.getSum = function() {
+ return this.sum;
+};
+
+/**
+ * Get the sum of squares of all added values
+ * @return {number} The sum of squares
+ */
+Histogram.prototype.sumOfSquares = function() {
+ return this.sum_of_squares;
+};
+
+/**
+ * Get the raw histogram as a list of bucket sizes
+ * @return {Array.} The buckets
+ */
+Histogram.prototype.getContents = function() {
+ return this.buckets;
+};
+
+module.exports = Histogram;
diff --git a/src/node/performance/perf_test.js b/src/node/performance/perf_test.js
deleted file mode 100644
index fe51e4a603e..00000000000
--- a/src/node/performance/perf_test.js
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-'use strict';
-
-var grpc = require('..');
-var testProto = grpc.load(__dirname + '/../interop/test.proto').grpc.testing;
-var _ = require('lodash');
-var interop_server = require('../interop/interop_server.js');
-
-function runTest(iterations, callback) {
- var testServer = interop_server.getServer(0, false);
- testServer.server.start();
- var client = new testProto.TestService('localhost:' + testServer.port,
- grpc.credentials.createInsecure());
-
- function runIterations(finish) {
- var start = process.hrtime();
- var intervals = [];
- function next(i) {
- if (i >= iterations) {
- testServer.server.shutdown();
- var totalDiff = process.hrtime(start);
- finish({
- total: totalDiff[0] * 1000000 + totalDiff[1] / 1000,
- intervals: intervals
- });
- } else{
- var deadline = new Date();
- deadline.setSeconds(deadline.getSeconds() + 3);
- var startTime = process.hrtime();
- client.emptyCall({}, function(err, resp) {
- var timeDiff = process.hrtime(startTime);
- intervals[i] = timeDiff[0] * 1000000 + timeDiff[1] / 1000;
- next(i+1);
- }, {}, {deadline: deadline});
- }
- }
- next(0);
- }
-
- function warmUp(num) {
- var pending = num;
- function startCall() {
- client.emptyCall({}, function(err, resp) {
- pending--;
- if (pending === 0) {
- runIterations(callback);
- }
- });
- }
- for (var i = 0; i < num; i++) {
- startCall();
- }
- }
- warmUp(100);
-}
-
-function percentile(arr, pct) {
- if (pct > 99) {
- pct = 99;
- }
- if (pct < 0) {
- pct = 0;
- }
- var index = Math.floor(arr.length * pct / 100);
- return arr[index];
-}
-
-if (require.main === module) {
- var count;
- if (process.argv.length >= 3) {
- count = process.argv[2];
- } else {
- count = 100;
- }
- runTest(count, function(results) {
- var sorted_intervals = _.sortBy(results.intervals, _.identity);
- console.log('count:', count);
- console.log('total time:', results.total, 'us');
- console.log('median:', percentile(sorted_intervals, 50), 'us');
- console.log('90th percentile:', percentile(sorted_intervals, 90), 'us');
- console.log('95th percentile:', percentile(sorted_intervals, 95), 'us');
- console.log('99th percentile:', percentile(sorted_intervals, 99), 'us');
- console.log('QPS:', (count / results.total) * 1000000);
- });
-}
-
-module.exports = runTest;
diff --git a/src/node/performance/qps_test.js b/src/node/performance/qps_test.js
deleted file mode 100644
index 491f47364c0..00000000000
--- a/src/node/performance/qps_test.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * This script runs a QPS test. It sends requests for a specified length of time
- * with a specified number pending at any one time. It then outputs the measured
- * QPS. Usage:
- * node qps_test.js [--concurrent=count] [--time=seconds]
- * concurrent defaults to 100 and time defaults to 10
- */
-
-'use strict';
-
-var async = require('async');
-var parseArgs = require('minimist');
-
-var grpc = require('..');
-var testProto = grpc.load(__dirname + '/../interop/test.proto').grpc.testing;
-var interop_server = require('../interop/interop_server.js');
-
-/**
- * Runs the QPS test. Sends requests constantly for the given number of seconds,
- * and keeps concurrent_calls requests pending at all times. When the test ends,
- * the callback is called with the number of calls that completed within the
- * time limit.
- * @param {number} concurrent_calls The number of calls to have pending
- * simultaneously
- * @param {number} seconds The number of seconds to run the test for
- * @param {function(Error, number)} callback Callback for test completion
- */
-function runTest(concurrent_calls, seconds, callback) {
- var testServer = interop_server.getServer(0, false);
- testServer.server.start();
- var client = new testProto.TestService('localhost:' + testServer.port,
- grpc.credentials.createInsecure());
-
- var warmup_num = 100;
-
- /**
- * Warms up the client to avoid counting startup time in the test result
- * @param {function(Error)} callback Called when warmup is complete
- */
- function warmUp(callback) {
- var pending = warmup_num;
- function startCall() {
- client.emptyCall({}, function(err, resp) {
- if (err) {
- callback(err);
- return;
- }
- pending--;
- if (pending === 0) {
- callback(null);
- }
- });
- }
- for (var i = 0; i < warmup_num; i++) {
- startCall();
- }
- }
- /**
- * Run the QPS test. Starts concurrent_calls requests, then starts a new
- * request whenever one completes until time runs out.
- * @param {function(Error, number)} callback Called when the test is complete.
- * The second argument is the number of calls that finished within the
- * time limit
- */
- function run(callback) {
- var running = 0;
- var count = 0;
- var start = process.hrtime();
- function responseCallback(err, resp) {
- if (process.hrtime(start)[0] < seconds) {
- count += 1;
- client.emptyCall({}, responseCallback);
- } else {
- running -= 1;
- if (running <= 0) {
- callback(null, count);
- }
- }
- }
- for (var i = 0; i < concurrent_calls; i++) {
- running += 1;
- client.emptyCall({}, responseCallback);
- }
- }
- async.waterfall([warmUp, run], function(err, count) {
- testServer.server.shutdown();
- callback(err, count);
- });
-}
-
-if (require.main === module) {
- var argv = parseArgs(process.argv.slice(2), {
- default: {'concurrent': 100,
- 'time': 10}
- });
- runTest(argv.concurrent, argv.time, function(err, count) {
- if (err) {
- throw err;
- }
- console.log('Concurrent calls:', argv.concurrent);
- console.log('Time:', argv.time, 'seconds');
- console.log('QPS:', (count/argv.time));
- });
-}
diff --git a/src/python/grpcio/grpc/_adapter/_c/module.c b/src/node/performance/worker_server.js
similarity index 65%
rename from src/python/grpcio/grpc/_adapter/_c/module.c
rename to src/node/performance/worker_server.js
index 9b93b051f67..43b86e5ecfa 100644
--- a/src/python/grpcio/grpc/_adapter/_c/module.c
+++ b/src/node/performance/worker_server.js
@@ -31,37 +31,33 @@
*
*/
-#include
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-
-#include "grpc/_adapter/_c/types.h"
-
-static PyMethodDef c_methods[] = {
- {NULL}
-};
-
-PyMODINIT_FUNC init_c(void) {
- PyObject *module;
-
- module = Py_InitModule3("_c", c_methods,
- "Wrappings of C structures and functions.");
-
- if (pygrpc_module_add_types(module) < 0) {
- return;
- }
-
- if (PyModule_AddStringConstant(
- module, "PRIMARY_USER_AGENT_KEY",
- GRPC_ARG_PRIMARY_USER_AGENT_STRING) < 0) {
- return;
- }
+'use strict';
+
+var worker_service_impl = require('./worker_service_impl');
+
+var grpc = require('../../../');
+var serviceProto = grpc.load({
+ root: __dirname + '/../../..',
+ file: 'test/proto/benchmarks/services.proto'}).grpc.testing;
+
+function runServer(port) {
+ var server_creds = grpc.ServerCredentials.createInsecure();
+ var server = new grpc.Server();
+ server.addProtoService(serviceProto.WorkerService.service,
+ worker_service_impl);
+ var address = '0.0.0.0:' + port;
+ server.bind(address, server_creds);
+ server.start();
+ return server;
+}
- /* GRPC maintains an internal counter of how many times it has been
- initialized and handles multiple pairs of grpc_init()/grpc_shutdown()
- invocations accordingly. */
- grpc_init();
- atexit(&grpc_shutdown);
+if (require.main === module) {
+ Error.stackTraceLimit = Infinity;
+ var parseArgs = require('minimist');
+ var argv = parseArgs(process.argv, {
+ string: ['driver_port']
+ });
+ runServer(argv.driver_port);
}
+
+exports.runServer = runServer;
diff --git a/src/node/performance/worker_service_impl.js b/src/node/performance/worker_service_impl.js
new file mode 100644
index 00000000000..8841ae13c3e
--- /dev/null
+++ b/src/node/performance/worker_service_impl.js
@@ -0,0 +1,132 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+'use strict';
+
+var BenchmarkClient = require('./benchmark_client');
+var BenchmarkServer = require('./benchmark_server');
+
+exports.runClient = function runClient(call) {
+ var client;
+ call.on('data', function(request) {
+ var stats;
+ switch (request.argtype) {
+ case 'setup':
+ var setup = request.setup;
+ client = new BenchmarkClient(setup.server_targets,
+ setup.client_channels,
+ setup.histogram_params,
+ setup.security_params);
+ client.on('error', function(error) {
+ call.emit('error', error);
+ });
+ switch (setup.load_params.load) {
+ case 'closed_loop':
+ client.startClosedLoop(setup.outstanding_rpcs_per_channel,
+ setup.rpc_type,
+ setup.payload_config.simple_params.req_size,
+ setup.payload_config.simple_params.resp_size);
+ break;
+ case 'poisson':
+ client.startPoisson(setup.outstanding_rpcs_per_channel,
+ setup.rpc_type, setup.payload_config.req_size,
+ setup.payload_config.resp_size,
+ setup.load_params.poisson.offered_load);
+ break;
+ default:
+ call.emit('error', new Error('Unsupported LoadParams type' +
+ setup.load_params.load));
+ }
+ stats = client.mark();
+ call.write({
+ stats: stats
+ });
+ break;
+ case 'mark':
+ if (client) {
+ stats = client.mark(request.mark.reset);
+ call.write({
+ stats: stats
+ });
+ } else {
+ call.emit('error', new Error('Got Mark before ClientConfig'));
+ }
+ break;
+ default:
+ throw new Error('Nonexistent client argtype option: ' + request.argtype);
+ }
+ });
+ call.on('end', function() {
+ client.stop(function() {
+ call.end();
+ });
+ });
+};
+
+exports.runServer = function runServer(call) {
+ var server;
+ call.on('data', function(request) {
+ var stats;
+ switch (request.argtype) {
+ case 'setup':
+ server = new BenchmarkServer(request.setup.host, request.setup.port,
+ request.setup.security_params);
+ server.start();
+ stats = server.mark();
+ call.write({
+ stats: stats,
+ port: server.getPort()
+ });
+ break;
+ case 'mark':
+ if (server) {
+ stats = server.mark(request.mark.reset);
+ call.write({
+ stats: stats,
+ port: server.getPort(),
+ cores: 1
+ });
+ } else {
+ call.emit('error', new Error('Got Mark before ServerConfig'));
+ }
+ break;
+ default:
+ throw new Error('Nonexistent server argtype option');
+ }
+ });
+ call.on('end', function() {
+ server.stop(function() {
+ call.end();
+ });
+ });
+};
diff --git a/src/node/test/async_test.js b/src/node/test/async_test.js
index 0af63c379e1..c46e745116e 100644
--- a/src/node/test/async_test.js
+++ b/src/node/test/async_test.js
@@ -36,7 +36,7 @@
var assert = require('assert');
var grpc = require('..');
-var math = grpc.load(__dirname + '/math/math.proto').math;
+var math = grpc.load(__dirname + '/../../proto/math/math.proto').math;
/**
diff --git a/src/node/test/math/math.proto b/src/node/test/math/math.proto
deleted file mode 100644
index 311e148c021..00000000000
--- a/src/node/test/math/math.proto
+++ /dev/null
@@ -1,80 +0,0 @@
-
-// Copyright 2015, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package math;
-
-message DivArgs {
- int64 dividend = 1;
- int64 divisor = 2;
-}
-
-message DivReply {
- int64 quotient = 1;
- int64 remainder = 2;
-}
-
-message FibArgs {
- int64 limit = 1;
-}
-
-message Num {
- int64 num = 1;
-}
-
-message FibReply {
- int64 count = 1;
-}
-
-service Math {
- // Div divides args.dividend by args.divisor and returns the quotient and
- // remainder.
- rpc Div (DivArgs) returns (DivReply) {
- }
-
- // DivMany accepts an arbitrary number of division args from the client stream
- // and sends back the results in the reply stream. The stream continues until
- // the client closes its end; the server does the same after sending all the
- // replies. The stream ends immediately if either end aborts.
- rpc DivMany (stream DivArgs) returns (stream DivReply) {
- }
-
- // Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib
- // generates up to limit numbers; otherwise it continues until the call is
- // canceled. Unlike Fib above, Fib has no final FibReply.
- rpc Fib (FibArgs) returns (stream Num) {
- }
-
- // Sum sums a stream of numbers, returning the final result once the stream
- // is closed.
- rpc Sum (stream Num) returns (Num) {
- }
-}
diff --git a/src/node/test/math/math_server.js b/src/node/test/math/math_server.js
index 9d06596f3d3..9f67c52ab0c 100644
--- a/src/node/test/math/math_server.js
+++ b/src/node/test/math/math_server.js
@@ -34,7 +34,8 @@
'use strict';
var grpc = require('../..');
-var math = grpc.load(__dirname + '/math.proto').math;
+var math = grpc.load(__dirname + '/../../../proto/math/math.proto').math;
+
/**
* Server function for division. Provides the /Math/DivMany and /Math/Div
diff --git a/src/node/test/math_client_test.js b/src/node/test/math_client_test.js
index 6361d97857a..3d446105364 100644
--- a/src/node/test/math_client_test.js
+++ b/src/node/test/math_client_test.js
@@ -36,7 +36,7 @@
var assert = require('assert');
var grpc = require('..');
-var math = grpc.load(__dirname + '/math/math.proto').math;
+var math = grpc.load(__dirname + '/../../proto/math/math.proto').math;
/**
* Client to use to make requests to a running server.
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 523fda6849d..fc765ed7314 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -41,7 +41,8 @@ var ProtoBuf = require('protobufjs');
var grpc = require('..');
-var math_proto = ProtoBuf.loadProtoFile(__dirname + '/math/math.proto');
+var math_proto = ProtoBuf.loadProtoFile(__dirname +
+ '/../../proto/math/math.proto');
var mathService = math_proto.lookup('math.Math');
diff --git a/src/php/tests/generated_code/math.proto b/src/php/tests/generated_code/math.proto
index 1de7d0b8deb..c872ee6e0b2 100644
--- a/src/php/tests/generated_code/math.proto
+++ b/src/php/tests/generated_code/math.proto
@@ -28,6 +28,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// TODO: start using src/proto/math/math.proto and remove this file once
+// PHP supports proto3.
+
syntax = "proto2";
package math;
diff --git a/src/ruby/pb/grpc/health/v1alpha/health.proto b/src/proto/grpc/health/v1alpha/health.proto
similarity index 97%
rename from src/ruby/pb/grpc/health/v1alpha/health.proto
rename to src/proto/grpc/health/v1alpha/health.proto
index d31df1e0a7c..28786c4427d 100644
--- a/src/ruby/pb/grpc/health/v1alpha/health.proto
+++ b/src/proto/grpc/health/v1alpha/health.proto
@@ -30,6 +30,7 @@
syntax = "proto3";
package grpc.health.v1alpha;
+option csharp_namespace = "Grpc.Health.V1Alpha";
message HealthCheckRequest {
string host = 1;
diff --git a/src/csharp/Grpc.Examples/proto/math.proto b/src/proto/math/math.proto
similarity index 100%
rename from src/csharp/Grpc.Examples/proto/math.proto
rename to src/proto/math/math.proto
diff --git a/src/python/grpcio/grpc/_adapter/_c/types.h b/src/python/grpcio/grpc/_adapter/_c/types.h
deleted file mode 100644
index 9ab415d216b..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types.h
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC__ADAPTER__C_TYPES_H_
-#define GRPC__ADAPTER__C_TYPES_H_
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-
-
-/*=========================*/
-/* Client-side credentials */
-/*=========================*/
-
-typedef struct ChannelCredentials {
- PyObject_HEAD
- grpc_channel_credentials *c_creds;
-} ChannelCredentials;
-void pygrpc_ChannelCredentials_dealloc(ChannelCredentials *self);
-ChannelCredentials *pygrpc_ChannelCredentials_google_default(
- PyTypeObject *type, PyObject *ignored);
-ChannelCredentials *pygrpc_ChannelCredentials_ssl(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-ChannelCredentials *pygrpc_ChannelCredentials_composite(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-extern PyTypeObject pygrpc_ChannelCredentials_type;
-
-typedef struct CallCredentials {
- PyObject_HEAD
- grpc_call_credentials *c_creds;
-} CallCredentials;
-void pygrpc_CallCredentials_dealloc(CallCredentials *self);
-CallCredentials *pygrpc_CallCredentials_composite(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-CallCredentials *pygrpc_CallCredentials_compute_engine(
- PyTypeObject *type, PyObject *ignored);
-CallCredentials *pygrpc_CallCredentials_jwt(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-CallCredentials *pygrpc_CallCredentials_refresh_token(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-CallCredentials *pygrpc_CallCredentials_iam(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-extern PyTypeObject pygrpc_CallCredentials_type;
-
-/*=========================*/
-/* Server-side credentials */
-/*=========================*/
-
-typedef struct ServerCredentials {
- PyObject_HEAD
- grpc_server_credentials *c_creds;
-} ServerCredentials;
-void pygrpc_ServerCredentials_dealloc(ServerCredentials *self);
-ServerCredentials *pygrpc_ServerCredentials_ssl(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-extern PyTypeObject pygrpc_ServerCredentials_type;
-
-
-/*==================*/
-/* Completion queue */
-/*==================*/
-
-typedef struct CompletionQueue {
- PyObject_HEAD
- grpc_completion_queue *c_cq;
-} CompletionQueue;
-CompletionQueue *pygrpc_CompletionQueue_new(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-void pygrpc_CompletionQueue_dealloc(CompletionQueue *self);
-PyObject *pygrpc_CompletionQueue_next(
- CompletionQueue *self, PyObject *args, PyObject *kwargs);
-PyObject *pygrpc_CompletionQueue_shutdown(
- CompletionQueue *self, PyObject *ignored);
-extern PyTypeObject pygrpc_CompletionQueue_type;
-
-
-/*======*/
-/* Call */
-/*======*/
-
-typedef struct Call {
- PyObject_HEAD
- grpc_call *c_call;
- CompletionQueue *cq;
-} Call;
-Call *pygrpc_Call_new_empty(CompletionQueue *cq);
-void pygrpc_Call_dealloc(Call *self);
-PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs);
-PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs);
-PyObject *pygrpc_Call_peer(Call *self);
-PyObject *pygrpc_Call_set_credentials(Call *self, PyObject *args,
- PyObject *kwargs);
-extern PyTypeObject pygrpc_Call_type;
-
-
-/*=========*/
-/* Channel */
-/*=========*/
-
-typedef struct Channel {
- PyObject_HEAD
- grpc_channel *c_chan;
-} Channel;
-Channel *pygrpc_Channel_new(
- PyTypeObject *type, PyObject *args, PyObject *kwargs);
-void pygrpc_Channel_dealloc(Channel *self);
-Call *pygrpc_Channel_create_call(
- Channel *self, PyObject *args, PyObject *kwargs);
-PyObject *pygrpc_Channel_check_connectivity_state(Channel *self, PyObject *args,
- PyObject *kwargs);
-PyObject *pygrpc_Channel_watch_connectivity_state(Channel *self, PyObject *args,
- PyObject *kwargs);
-PyObject *pygrpc_Channel_target(Channel *self);
-extern PyTypeObject pygrpc_Channel_type;
-
-
-/*========*/
-/* Server */
-/*========*/
-
-typedef struct Server {
- PyObject_HEAD
- grpc_server *c_serv;
- CompletionQueue *cq;
- int shutdown_called;
-} Server;
-Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs);
-void pygrpc_Server_dealloc(Server *self);
-PyObject *pygrpc_Server_request_call(
- Server *self, PyObject *args, PyObject *kwargs);
-PyObject *pygrpc_Server_add_http2_port(
- Server *self, PyObject *args, PyObject *kwargs);
-PyObject *pygrpc_Server_start(Server *self, PyObject *ignored);
-PyObject *pygrpc_Server_shutdown(
- Server *self, PyObject *args, PyObject *kwargs);
-PyObject *pygrpc_Server_cancel_all_calls(Server *self, PyObject *unused);
-extern PyTypeObject pygrpc_Server_type;
-
-/*=========*/
-/* Utility */
-/*=========*/
-
-/* Every tag that passes from Python GRPC to GRPC core is of this type. */
-typedef struct pygrpc_tag {
- PyObject *user_tag;
- Call *call;
- grpc_call_details request_call_details;
- grpc_metadata_array request_metadata;
- grpc_op *ops;
- size_t nops;
- int is_new_call;
-} pygrpc_tag;
-
-/* Construct a tag associated with a batch call. Does not take ownership of the
- resources in the elements of ops. */
-pygrpc_tag *pygrpc_produce_batch_tag(PyObject *user_tag, Call *call,
- grpc_op *ops, size_t nops);
-
-
-/* Construct a tag associated with a server request. The calling code should
- use the appropriate fields of the produced tag in the invocation of
- grpc_server_request_call. */
-pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call);
-
-/* Construct a tag associated with a server shutdown. */
-pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag);
-
-/* Construct a tag associated with a channel state change. */
-pygrpc_tag *pygrpc_produce_channel_state_change_tag(PyObject *user_tag);
-
-/* Frees all resources owned by the tag and the tag itself. */
-void pygrpc_discard_tag(pygrpc_tag *tag);
-
-/* Consumes an event and its associated tag, providing a Python tuple of the
- form `(type, tag, call, call_details, results)` (where type is an integer
- corresponding to a grpc_completion_type, tag is an arbitrary PyObject, call
- is the call object associated with the event [if any], call_details is a
- tuple of form `(method, host, deadline)` [if such details are available],
- and resultd is a list of tuples of form `(type, metadata, message, status,
- cancelled)` [where type corresponds to a grpc_op_type, metadata is a
- sequence of 2-sequences of strings, message is a byte string, and status is
- a 2-tuple of an integer corresponding to grpc_status_code and a string of
- status details]).
-
- Frees all resources associated with the event tag. */
-PyObject *pygrpc_consume_event(grpc_event event);
-
-/* Transliterate the Python tuple of form `(type, metadata, message,
- status)` (where type is an integer corresponding to a grpc_op_type, metadata
- is a sequence of 2-sequences of strings, message is a byte string, and
- status is 2-tuple of an integer corresponding to grpc_status_code and a
- string of status details) to a grpc_op suitable for use in a
- grpc_call_start_batch invocation. The grpc_op is a 'directory' of resources
- that must be freed after GRPC core is done with them.
-
- Calls gpr_malloc (or the appropriate type-specific grpc_*_create function)
- to populate the appropriate union-discriminated members of the op.
-
- Returns true on success, false on failure. */
-int pygrpc_produce_op(PyObject *op, grpc_op *result);
-
-/* Discards all resources associated with the passed in op that was produced by
- pygrpc_produce_op. */
-void pygrpc_discard_op(grpc_op op);
-
-/* Transliterate the grpc_ops (which have been sent through a
- grpc_call_start_batch invocation and whose corresponding event has appeared
- on a completion queue) to a Python tuple of form `(type, metadata, message,
- status, cancelled)` (where type is an integer corresponding to a
- grpc_op_type, metadata is a sequence of 2-sequences of strings, message is a
- byte string, and status is 2-tuple of an integer corresponding to
- grpc_status_code and a string of status details).
-
- Calls gpr_free (or the appropriate type-specific grpc_*_destroy function) on
- the appropriate union-discriminated populated members of the ops. */
-PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops);
-
-/* Transliterate from a gpr_timespec to a double (in units of seconds, either
- from the epoch if interpreted absolutely or as a delta otherwise). */
-double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec);
-
-/* Transliterate from a double (in units of seconds from the epoch if
- interpreted absolutely or as a delta otherwise) to a gpr_timespec. */
-gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds);
-
-/* Returns true on success, false on failure. */
-int pygrpc_cast_pyseq_to_send_metadata(
- PyObject *pyseq, grpc_metadata **metadata, size_t *count);
-/* Returns a metadata array as a Python object on success, else NULL. */
-PyObject *pygrpc_cast_metadata_array_to_pyseq(grpc_metadata_array metadata);
-
-/* Transliterate from a list of python channel arguments (2-tuples of string
- and string|integer|None) to a grpc_channel_args object. The strings placed
- in the grpc_channel_args object's grpc_arg elements are views of the Python
- object. The Python object must live long enough for the grpc_channel_args
- to be used. Arguments set to None are silently ignored. Returns true on
- success, false on failure. */
-int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args);
-void pygrpc_discard_channel_args(grpc_channel_args args);
-
-/* Read the bytes from grpc_byte_buffer to a gpr_malloc'd array of bytes;
- output to result and result_size. */
-void pygrpc_byte_buffer_to_bytes(
- grpc_byte_buffer *buffer, char **result, size_t *result_size);
-
-
-/*========*/
-/* Module */
-/*========*/
-
-/* Returns 0 on success, -1 on failure. */
-int pygrpc_module_add_types(PyObject *module);
-
-#endif /* GRPC__ADAPTER__C_TYPES_H_ */
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/call.c b/src/python/grpcio/grpc/_adapter/_c/types/call.c
deleted file mode 100644
index 04ec8718800..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types/call.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_c/types.h"
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-
-
-PyMethodDef pygrpc_Call_methods[] = {
- {"start_batch", (PyCFunction)pygrpc_Call_start_batch, METH_KEYWORDS, ""},
- {"cancel", (PyCFunction)pygrpc_Call_cancel, METH_KEYWORDS, ""},
- {"peer", (PyCFunction)pygrpc_Call_peer, METH_NOARGS, ""},
- {"set_credentials", (PyCFunction)pygrpc_Call_set_credentials, METH_KEYWORDS,
- ""},
- {NULL}
-};
-const char pygrpc_Call_doc[] = "See grpc._adapter._types.Call.";
-PyTypeObject pygrpc_Call_type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "Call", /* tp_name */
- sizeof(Call), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)pygrpc_Call_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- pygrpc_Call_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygrpc_Call_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0 /* tp_new */
-};
-
-Call *pygrpc_Call_new_empty(CompletionQueue *cq) {
- Call *call = (Call *)pygrpc_Call_type.tp_alloc(&pygrpc_Call_type, 0);
- call->c_call = NULL;
- call->cq = cq;
- Py_XINCREF(call->cq);
- return call;
-}
-void pygrpc_Call_dealloc(Call *self) {
- if (self->c_call) {
- grpc_call_destroy(self->c_call);
- }
- Py_XDECREF(self->cq);
- self->ob_type->tp_free((PyObject *)self);
-}
-PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs) {
- PyObject *op_list;
- PyObject *user_tag;
- grpc_op *ops;
- size_t nops;
- size_t i;
- size_t j;
- pygrpc_tag *tag;
- grpc_call_error errcode;
- static char *keywords[] = {"ops", "tag", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO:start_batch", keywords,
- &op_list, &user_tag)) {
- return NULL;
- }
- if (!PyList_Check(op_list)) {
- PyErr_SetString(PyExc_TypeError, "expected a list of OpArgs");
- return NULL;
- }
- nops = PyList_Size(op_list);
- ops = gpr_malloc(sizeof(grpc_op) * nops);
- for (i = 0; i < nops; ++i) {
- PyObject *item = PyList_GET_ITEM(op_list, i);
- if (!pygrpc_produce_op(item, &ops[i])) {
- for (j = 0; j < i; ++j) {
- pygrpc_discard_op(ops[j]);
- }
- return NULL;
- }
- }
- tag = pygrpc_produce_batch_tag(user_tag, self, ops, nops);
- errcode = grpc_call_start_batch(self->c_call, tag->ops, tag->nops, tag, NULL);
- gpr_free(ops);
- return PyInt_FromLong(errcode);
-}
-PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs) {
- PyObject *py_code = NULL;
- grpc_call_error errcode;
- int code;
- char *details = NULL;
- static char *keywords[] = {"code", "details", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Os:start_batch", keywords,
- &py_code, &details)) {
- return NULL;
- }
- if (py_code != NULL && details != NULL) {
- if (!PyInt_Check(py_code)) {
- PyErr_SetString(PyExc_TypeError, "expected integer code");
- return NULL;
- }
- code = PyInt_AsLong(py_code);
- errcode = grpc_call_cancel_with_status(self->c_call, code, details, NULL);
- } else if (py_code != NULL || details != NULL) {
- PyErr_SetString(PyExc_ValueError,
- "if `code` is specified, so must `details`");
- return NULL;
- } else {
- errcode = grpc_call_cancel(self->c_call, NULL);
- }
- return PyInt_FromLong(errcode);
-}
-
-PyObject *pygrpc_Call_peer(Call *self) {
- char *peer = grpc_call_get_peer(self->c_call);
- PyObject *py_peer = PyString_FromString(peer);
- gpr_free(peer);
- return py_peer;
-}
-PyObject *pygrpc_Call_set_credentials(Call *self, PyObject *args,
- PyObject *kwargs) {
- CallCredentials *creds;
- grpc_call_error errcode;
- static char *keywords[] = {"creds", NULL};
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "O!:set_credentials", keywords,
- &pygrpc_CallCredentials_type, &creds)) {
- return NULL;
- }
- errcode = grpc_call_set_credentials(self->c_call, creds->c_creds);
- return PyInt_FromLong(errcode);
-}
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c
deleted file mode 100644
index 5a15a6e17dc..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_c/types.h"
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-
-
-PyMethodDef pygrpc_CallCredentials_methods[] = {
- {"composite", (PyCFunction)pygrpc_CallCredentials_composite,
- METH_CLASS|METH_KEYWORDS, ""},
- {"compute_engine", (PyCFunction)pygrpc_CallCredentials_compute_engine,
- METH_CLASS|METH_NOARGS, ""},
- {"jwt", (PyCFunction)pygrpc_CallCredentials_jwt,
- METH_CLASS|METH_KEYWORDS, ""},
- {"refresh_token", (PyCFunction)pygrpc_CallCredentials_refresh_token,
- METH_CLASS|METH_KEYWORDS, ""},
- {"iam", (PyCFunction)pygrpc_CallCredentials_iam,
- METH_CLASS|METH_KEYWORDS, ""},
- {NULL}
-};
-
-const char pygrpc_CallCredentials_doc[] = "";
-PyTypeObject pygrpc_CallCredentials_type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "CallCredentials", /* tp_name */
- sizeof(CallCredentials), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)pygrpc_CallCredentials_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- pygrpc_CallCredentials_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygrpc_CallCredentials_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0 /* tp_new */
-};
-
-void pygrpc_CallCredentials_dealloc(CallCredentials *self) {
- grpc_call_credentials_release(self->c_creds);
- self->ob_type->tp_free((PyObject *)self);
-}
-
-CallCredentials *pygrpc_CallCredentials_composite(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- CallCredentials *self;
- CallCredentials *creds1;
- CallCredentials *creds2;
- static char *keywords[] = {"creds1", "creds2", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords,
- &pygrpc_CallCredentials_type, &creds1,
- &pygrpc_CallCredentials_type, &creds2)) {
- return NULL;
- }
- self = (CallCredentials *)type->tp_alloc(type, 0);
- self->c_creds =
- grpc_composite_call_credentials_create(
- creds1->c_creds, creds2->c_creds, NULL);
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError, "couldn't create composite credentials");
- return NULL;
- }
- return self;
-}
-
-CallCredentials *pygrpc_CallCredentials_compute_engine(
- PyTypeObject *type, PyObject *ignored) {
- CallCredentials *self = (CallCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_google_compute_engine_credentials_create(NULL);
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError,
- "couldn't create compute engine credentials");
- return NULL;
- }
- return self;
-}
-
-/* TODO: Rename this credentials to something like service_account_jwt_access */
-CallCredentials *pygrpc_CallCredentials_jwt(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- CallCredentials *self;
- const char *json_key;
- double lifetime;
- static char *keywords[] = {"json_key", "token_lifetime", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sd:jwt", keywords,
- &json_key, &lifetime)) {
- return NULL;
- }
- self = (CallCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_service_account_jwt_access_credentials_create(
- json_key, pygrpc_cast_double_to_gpr_timespec(lifetime), NULL);
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError, "couldn't create JWT credentials");
- return NULL;
- }
- return self;
-}
-
-CallCredentials *pygrpc_CallCredentials_refresh_token(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- CallCredentials *self;
- const char *json_refresh_token;
- static char *keywords[] = {"json_refresh_token", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:refresh_token", keywords,
- &json_refresh_token)) {
- return NULL;
- }
- self = (CallCredentials *)type->tp_alloc(type, 0);
- self->c_creds =
- grpc_google_refresh_token_credentials_create(json_refresh_token, NULL);
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError,
- "couldn't create credentials from refresh token");
- return NULL;
- }
- return self;
-}
-
-CallCredentials *pygrpc_CallCredentials_iam(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- CallCredentials *self;
- const char *authorization_token;
- const char *authority_selector;
- static char *keywords[] = {"authorization_token", "authority_selector", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss:iam", keywords,
- &authorization_token, &authority_selector)) {
- return NULL;
- }
- self = (CallCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_google_iam_credentials_create(authorization_token,
- authority_selector, NULL);
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError, "couldn't create IAM credentials");
- return NULL;
- }
- return self;
-}
-
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel.c b/src/python/grpcio/grpc/_adapter/_c/types/channel.c
deleted file mode 100644
index c4db2a0dfde..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types/channel.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_c/types.h"
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-
-
-PyMethodDef pygrpc_Channel_methods[] = {
- {"create_call", (PyCFunction)pygrpc_Channel_create_call, METH_KEYWORDS, ""},
- {"check_connectivity_state", (PyCFunction)pygrpc_Channel_check_connectivity_state, METH_KEYWORDS, ""},
- {"watch_connectivity_state", (PyCFunction)pygrpc_Channel_watch_connectivity_state, METH_KEYWORDS, ""},
- {"target", (PyCFunction)pygrpc_Channel_target, METH_NOARGS, ""},
- {NULL}
-};
-const char pygrpc_Channel_doc[] = "See grpc._adapter._types.Channel.";
-PyTypeObject pygrpc_Channel_type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "Channel", /* tp_name */
- sizeof(Channel), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)pygrpc_Channel_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- pygrpc_Channel_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygrpc_Channel_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- (newfunc)pygrpc_Channel_new /* tp_new */
-};
-
-Channel *pygrpc_Channel_new(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- Channel *self;
- const char *target;
- PyObject *py_args;
- ChannelCredentials *creds = NULL;
- grpc_channel_args c_args;
- char *keywords[] = {"target", "args", "creds", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|O!:Channel", keywords,
- &target, &py_args, &pygrpc_ChannelCredentials_type, &creds)) {
- return NULL;
- }
- if (!pygrpc_produce_channel_args(py_args, &c_args)) {
- return NULL;
- }
- self = (Channel *)type->tp_alloc(type, 0);
- if (creds) {
- self->c_chan =
- grpc_secure_channel_create(creds->c_creds, target, &c_args, NULL);
- } else {
- self->c_chan = grpc_insecure_channel_create(target, &c_args, NULL);
- }
- pygrpc_discard_channel_args(c_args);
- return self;
-}
-void pygrpc_Channel_dealloc(Channel *self) {
- grpc_channel_destroy(self->c_chan);
- self->ob_type->tp_free((PyObject *)self);
-}
-
-Call *pygrpc_Channel_create_call(
- Channel *self, PyObject *args, PyObject *kwargs) {
- Call *call;
- CompletionQueue *cq;
- const char *method;
- const char *host;
- double deadline;
- char *keywords[] = {"cq", "method", "host", "deadline", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!szd:create_call", keywords,
- &pygrpc_CompletionQueue_type, &cq, &method, &host, &deadline)) {
- return NULL;
- }
- call = pygrpc_Call_new_empty(cq);
- call->c_call = grpc_channel_create_call(
- self->c_chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq->c_cq, method, host,
- pygrpc_cast_double_to_gpr_timespec(deadline), NULL);
- return call;
-}
-
-PyObject *pygrpc_Channel_check_connectivity_state(
- Channel *self, PyObject *args, PyObject *kwargs) {
- PyObject *py_try_to_connect;
- int try_to_connect;
- char *keywords[] = {"try_to_connect", NULL};
- grpc_connectivity_state state;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:connectivity_state", keywords,
- &py_try_to_connect)) {
- return NULL;
- }
- if (!PyBool_Check(py_try_to_connect)) {
- Py_XDECREF(py_try_to_connect);
- return NULL;
- }
- try_to_connect = Py_True == py_try_to_connect;
- Py_DECREF(py_try_to_connect);
- state = grpc_channel_check_connectivity_state(self->c_chan, try_to_connect);
- return PyInt_FromLong(state);
-}
-
-PyObject *pygrpc_Channel_watch_connectivity_state(
- Channel *self, PyObject *args, PyObject *kwargs) {
- PyObject *tag;
- double deadline;
- int last_observed_state;
- CompletionQueue *completion_queue;
- char *keywords[] = {"last_observed_state", "deadline",
- "completion_queue", "tag", NULL};
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "idO!O:watch_connectivity_state", keywords,
- &last_observed_state, &deadline, &pygrpc_CompletionQueue_type,
- &completion_queue, &tag)) {
- return NULL;
- }
- grpc_channel_watch_connectivity_state(
- self->c_chan, (grpc_connectivity_state)last_observed_state,
- pygrpc_cast_double_to_gpr_timespec(deadline), completion_queue->c_cq,
- pygrpc_produce_channel_state_change_tag(tag));
- Py_RETURN_NONE;
-}
-
-PyObject *pygrpc_Channel_target(Channel *self) {
- char *target = grpc_channel_get_target(self->c_chan);
- PyObject *py_target = PyString_FromString(target);
- gpr_free(target);
- return py_target;
-}
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c
deleted file mode 100644
index 83b1fc0406a..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_c/types.h"
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-
-
-PyMethodDef pygrpc_ChannelCredentials_methods[] = {
- {"google_default", (PyCFunction)pygrpc_ChannelCredentials_google_default,
- METH_CLASS|METH_NOARGS, ""},
- {"ssl", (PyCFunction)pygrpc_ChannelCredentials_ssl,
- METH_CLASS|METH_KEYWORDS, ""},
- {"composite", (PyCFunction)pygrpc_ChannelCredentials_composite,
- METH_CLASS|METH_KEYWORDS, ""},
- {NULL}
-};
-
-const char pygrpc_ChannelCredentials_doc[] = "";
-PyTypeObject pygrpc_ChannelCredentials_type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "ChannelCredentials", /* tp_name */
- sizeof(ChannelCredentials), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)pygrpc_ChannelCredentials_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- pygrpc_ChannelCredentials_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygrpc_ChannelCredentials_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0 /* tp_new */
-};
-
-void pygrpc_ChannelCredentials_dealloc(ChannelCredentials *self) {
- grpc_channel_credentials_release(self->c_creds);
- self->ob_type->tp_free((PyObject *)self);
-}
-
-ChannelCredentials *pygrpc_ChannelCredentials_google_default(
- PyTypeObject *type, PyObject *ignored) {
- ChannelCredentials *self = (ChannelCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_google_default_credentials_create();
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError,
- "couldn't create Google default credentials");
- return NULL;
- }
- return self;
-}
-
-ChannelCredentials *pygrpc_ChannelCredentials_ssl(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- ChannelCredentials *self;
- const char *root_certs;
- const char *private_key = NULL;
- const char *cert_chain = NULL;
- grpc_ssl_pem_key_cert_pair key_cert_pair;
- static char *keywords[] = {"root_certs", "private_key", "cert_chain", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|zz:ssl", keywords,
- &root_certs, &private_key, &cert_chain)) {
- return NULL;
- }
- self = (ChannelCredentials *)type->tp_alloc(type, 0);
- if (private_key && cert_chain) {
- key_cert_pair.private_key = private_key;
- key_cert_pair.cert_chain = cert_chain;
- self->c_creds =
- grpc_ssl_credentials_create(root_certs, &key_cert_pair, NULL);
- } else {
- self->c_creds = grpc_ssl_credentials_create(root_certs, NULL, NULL);
- }
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError, "couldn't create ssl credentials");
- return NULL;
- }
- return self;
-}
-
-ChannelCredentials *pygrpc_ChannelCredentials_composite(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- ChannelCredentials *self;
- ChannelCredentials *creds1;
- CallCredentials *creds2;
- static char *keywords[] = {"creds1", "creds2", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords,
- &pygrpc_ChannelCredentials_type, &creds1,
- &pygrpc_CallCredentials_type, &creds2)) {
- return NULL;
- }
- self = (ChannelCredentials *)type->tp_alloc(type, 0);
- self->c_creds =
- grpc_composite_channel_credentials_create(
- creds1->c_creds, creds2->c_creds, NULL);
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(
- PyExc_RuntimeError, "couldn't create composite credentials");
- return NULL;
- }
- return self;
-}
-
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/completion_queue.c b/src/python/grpcio/grpc/_adapter/_c/types/completion_queue.c
deleted file mode 100644
index d8bb89ca4bc..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types/completion_queue.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_c/types.h"
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-
-
-PyMethodDef pygrpc_CompletionQueue_methods[] = {
- {"next", (PyCFunction)pygrpc_CompletionQueue_next, METH_KEYWORDS, ""},
- {"shutdown", (PyCFunction)pygrpc_CompletionQueue_shutdown, METH_NOARGS, ""},
- {NULL}
-};
-const char pygrpc_CompletionQueue_doc[] =
- "See grpc._adapter._types.CompletionQueue.";
-PyTypeObject pygrpc_CompletionQueue_type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "CompletionQueue", /* tp_name */
- sizeof(CompletionQueue), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)pygrpc_CompletionQueue_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- pygrpc_CompletionQueue_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygrpc_CompletionQueue_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- (newfunc)pygrpc_CompletionQueue_new /* tp_new */
-};
-
-CompletionQueue *pygrpc_CompletionQueue_new(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- CompletionQueue *self = (CompletionQueue *)type->tp_alloc(type, 0);
- self->c_cq = grpc_completion_queue_create(NULL);
- return self;
-}
-
-void pygrpc_CompletionQueue_dealloc(CompletionQueue *self) {
- grpc_completion_queue_destroy(self->c_cq);
- self->ob_type->tp_free((PyObject *)self);
-}
-
-PyObject *pygrpc_CompletionQueue_next(
- CompletionQueue *self, PyObject *args, PyObject *kwargs) {
- double deadline;
- grpc_event event;
- PyObject *transliterated_event;
- static char *keywords[] = {"deadline", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d:next", keywords,
- &deadline)) {
- return NULL;
- }
- Py_BEGIN_ALLOW_THREADS;
- event = grpc_completion_queue_next(
- self->c_cq, pygrpc_cast_double_to_gpr_timespec(deadline), NULL);
- Py_END_ALLOW_THREADS;
- transliterated_event = pygrpc_consume_event(event);
- return transliterated_event;
-}
-
-PyObject *pygrpc_CompletionQueue_shutdown(
- CompletionQueue *self, PyObject *ignored) {
- grpc_completion_queue_shutdown(self->c_cq);
- Py_RETURN_NONE;
-}
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/server.c b/src/python/grpcio/grpc/_adapter/_c/types/server.c
deleted file mode 100644
index 8feab8aab15..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types/server.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_c/types.h"
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-
-
-PyMethodDef pygrpc_Server_methods[] = {
- {"request_call", (PyCFunction)pygrpc_Server_request_call,
- METH_KEYWORDS, ""},
- {"add_http2_port", (PyCFunction)pygrpc_Server_add_http2_port,
- METH_KEYWORDS, ""},
- {"start", (PyCFunction)pygrpc_Server_start, METH_NOARGS, ""},
- {"shutdown", (PyCFunction)pygrpc_Server_shutdown, METH_KEYWORDS, ""},
- {"cancel_all_calls", (PyCFunction)pygrpc_Server_cancel_all_calls,
- METH_NOARGS, ""},
- {NULL}
-};
-const char pygrpc_Server_doc[] = "See grpc._adapter._types.Server.";
-PyTypeObject pygrpc_Server_type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "Server", /* tp_name */
- sizeof(Server), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)pygrpc_Server_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- pygrpc_Server_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygrpc_Server_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- (newfunc)pygrpc_Server_new /* tp_new */
-};
-
-Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- Server *self;
- CompletionQueue *cq;
- PyObject *py_args;
- grpc_channel_args c_args;
- char *keywords[] = {"cq", "args", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Server", keywords,
- &pygrpc_CompletionQueue_type, &cq, &py_args)) {
- return NULL;
- }
- if (!pygrpc_produce_channel_args(py_args, &c_args)) {
- return NULL;
- }
- self = (Server *)type->tp_alloc(type, 0);
- self->c_serv = grpc_server_create(&c_args, NULL);
- grpc_server_register_completion_queue(self->c_serv, cq->c_cq, NULL);
- pygrpc_discard_channel_args(c_args);
- self->cq = cq;
- Py_INCREF(self->cq);
- self->shutdown_called = 0;
- return self;
-}
-
-void pygrpc_Server_dealloc(Server *self) {
- grpc_server_destroy(self->c_serv);
- Py_XDECREF(self->cq);
- self->ob_type->tp_free((PyObject *)self);
-}
-
-PyObject *pygrpc_Server_request_call(
- Server *self, PyObject *args, PyObject *kwargs) {
- CompletionQueue *cq;
- PyObject *user_tag;
- pygrpc_tag *tag;
- Call *empty_call;
- grpc_call_error errcode;
- static char *keywords[] = {"cq", "tag", NULL};
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "O!O", keywords,
- &pygrpc_CompletionQueue_type, &cq, &user_tag)) {
- return NULL;
- }
- empty_call = pygrpc_Call_new_empty(cq);
- tag = pygrpc_produce_request_tag(user_tag, empty_call);
- errcode = grpc_server_request_call(
- self->c_serv, &tag->call->c_call, &tag->request_call_details,
- &tag->request_metadata, tag->call->cq->c_cq, self->cq->c_cq, tag);
- Py_DECREF(empty_call);
- return PyInt_FromLong(errcode);
-}
-
-PyObject *pygrpc_Server_add_http2_port(
- Server *self, PyObject *args, PyObject *kwargs) {
- const char *addr;
- ServerCredentials *creds = NULL;
- int port;
- static char *keywords[] = {"addr", "creds", NULL};
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "s|O!:add_http2_port", keywords,
- &addr, &pygrpc_ServerCredentials_type, &creds)) {
- return NULL;
- }
- if (creds) {
- port = grpc_server_add_secure_http2_port(
- self->c_serv, addr, creds->c_creds);
- } else {
- port = grpc_server_add_insecure_http2_port(self->c_serv, addr);
- }
- return PyInt_FromLong(port);
-
-}
-
-PyObject *pygrpc_Server_start(Server *self, PyObject *ignored) {
- grpc_server_start(self->c_serv);
- self->shutdown_called = 0;
- Py_RETURN_NONE;
-}
-
-PyObject *pygrpc_Server_shutdown(
- Server *self, PyObject *args, PyObject *kwargs) {
- PyObject *user_tag;
- pygrpc_tag *tag;
- static char *keywords[] = {"tag", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", keywords, &user_tag)) {
- return NULL;
- }
- tag = pygrpc_produce_server_shutdown_tag(user_tag);
- grpc_server_shutdown_and_notify(self->c_serv, self->cq->c_cq, tag);
- self->shutdown_called = 1;
- Py_RETURN_NONE;
-}
-
-PyObject *pygrpc_Server_cancel_all_calls(Server *self, PyObject *unused) {
- if (!self->shutdown_called) {
- PyErr_SetString(
- PyExc_RuntimeError,
- "shutdown must have been called prior to calling cancel_all_calls!");
- return NULL;
- }
- grpc_server_cancel_all_calls(self->c_serv);
- Py_RETURN_NONE;
-}
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c
deleted file mode 100644
index df51a99b6a9..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/types/server_credentials.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_c/types.h"
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-#include
-
-
-PyMethodDef pygrpc_ServerCredentials_methods[] = {
- {"ssl", (PyCFunction)pygrpc_ServerCredentials_ssl,
- METH_CLASS|METH_KEYWORDS, ""},
- {NULL}
-};
-const char pygrpc_ServerCredentials_doc[] = "";
-PyTypeObject pygrpc_ServerCredentials_type = {
- PyObject_HEAD_INIT(NULL)
- 0, /* ob_size */
- "ServerCredentials", /* tp_name */
- sizeof(ServerCredentials), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)pygrpc_ServerCredentials_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- pygrpc_ServerCredentials_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- pygrpc_ServerCredentials_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0 /* tp_new */
-};
-
-void pygrpc_ServerCredentials_dealloc(ServerCredentials *self) {
- grpc_server_credentials_release(self->c_creds);
- self->ob_type->tp_free((PyObject *)self);
-}
-
-ServerCredentials *pygrpc_ServerCredentials_ssl(
- PyTypeObject *type, PyObject *args, PyObject *kwargs) {
- ServerCredentials *self;
- const char *root_certs;
- PyObject *py_key_cert_pairs;
- grpc_ssl_pem_key_cert_pair *key_cert_pairs;
- int force_client_auth;
- size_t num_key_cert_pairs;
- size_t i;
- static char *keywords[] = {
- "root_certs", "key_cert_pairs", "force_client_auth", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zOi:ssl", keywords,
- &root_certs, &py_key_cert_pairs, &force_client_auth)) {
- return NULL;
- }
- if (!PyList_Check(py_key_cert_pairs)) {
- PyErr_SetString(PyExc_TypeError, "expected a list of 2-tuples of strings");
- return NULL;
- }
- num_key_cert_pairs = PyList_Size(py_key_cert_pairs);
- key_cert_pairs =
- gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
- for (i = 0; i < num_key_cert_pairs; ++i) {
- PyObject *item = PyList_GET_ITEM(py_key_cert_pairs, i);
- const char *key;
- const char *cert;
- if (!PyArg_ParseTuple(item, "zz", &key, &cert)) {
- gpr_free(key_cert_pairs);
- PyErr_SetString(PyExc_TypeError,
- "expected a list of 2-tuples of strings");
- return NULL;
- }
- key_cert_pairs[i].private_key = key;
- key_cert_pairs[i].cert_chain = cert;
- }
-
- self = (ServerCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_ssl_server_credentials_create(
- root_certs, key_cert_pairs, num_key_cert_pairs, force_client_auth, NULL);
- gpr_free(key_cert_pairs);
- return self;
-}
diff --git a/src/python/grpcio/grpc/_adapter/_c/utility.c b/src/python/grpcio/grpc/_adapter/_c/utility.c
deleted file mode 100644
index 590f7e013a2..00000000000
--- a/src/python/grpcio/grpc/_adapter/_c/utility.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include
-#include
-
-#define PY_SSIZE_T_CLEAN
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "grpc/_adapter/_c/types.h"
-
-pygrpc_tag *pygrpc_produce_batch_tag(
- PyObject *user_tag, Call *call, grpc_op *ops, size_t nops) {
- pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag));
- tag->user_tag = user_tag;
- Py_XINCREF(tag->user_tag);
- tag->call = call;
- Py_XINCREF(tag->call);
- tag->ops = gpr_malloc(sizeof(grpc_op)*nops);
- memcpy(tag->ops, ops, sizeof(grpc_op)*nops);
- tag->nops = nops;
- grpc_call_details_init(&tag->request_call_details);
- grpc_metadata_array_init(&tag->request_metadata);
- tag->is_new_call = 0;
- return tag;
-}
-
-pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call) {
- pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag));
- tag->user_tag = user_tag;
- Py_XINCREF(tag->user_tag);
- tag->call = empty_call;
- Py_XINCREF(tag->call);
- tag->ops = NULL;
- tag->nops = 0;
- grpc_call_details_init(&tag->request_call_details);
- grpc_metadata_array_init(&tag->request_metadata);
- tag->is_new_call = 1;
- return tag;
-}
-
-pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag) {
- pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag));
- tag->user_tag = user_tag;
- Py_XINCREF(tag->user_tag);
- tag->call = NULL;
- tag->ops = NULL;
- tag->nops = 0;
- grpc_call_details_init(&tag->request_call_details);
- grpc_metadata_array_init(&tag->request_metadata);
- tag->is_new_call = 0;
- return tag;
-}
-
-pygrpc_tag *pygrpc_produce_channel_state_change_tag(PyObject *user_tag) {
- pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag));
- tag->user_tag = user_tag;
- Py_XINCREF(tag->user_tag);
- tag->call = NULL;
- tag->ops = NULL;
- tag->nops = 0;
- grpc_call_details_init(&tag->request_call_details);
- grpc_metadata_array_init(&tag->request_metadata);
- tag->is_new_call = 0;
- return tag;
-}
-
-void pygrpc_discard_tag(pygrpc_tag *tag) {
- if (!tag) {
- return;
- }
- Py_XDECREF(tag->user_tag);
- Py_XDECREF(tag->call);
- gpr_free(tag->ops);
- grpc_call_details_destroy(&tag->request_call_details);
- grpc_metadata_array_destroy(&tag->request_metadata);
- gpr_free(tag);
-}
-
-PyObject *pygrpc_consume_event(grpc_event event) {
- pygrpc_tag *tag;
- PyObject *result;
- if (event.type == GRPC_QUEUE_TIMEOUT) {
- Py_RETURN_NONE;
- }
- tag = event.tag;
- switch (event.type) {
- case GRPC_QUEUE_SHUTDOWN:
- result = Py_BuildValue("iOOOOO", GRPC_QUEUE_SHUTDOWN,
- Py_None, Py_None, Py_None, Py_None, Py_True);
- break;
- case GRPC_OP_COMPLETE:
- if (tag->is_new_call) {
- result = Py_BuildValue(
- "iOO(ssd)[(iNOOOO)]O", GRPC_OP_COMPLETE, tag->user_tag, tag->call,
- tag->request_call_details.method, tag->request_call_details.host,
- pygrpc_cast_gpr_timespec_to_double(tag->request_call_details.deadline),
- GRPC_OP_RECV_INITIAL_METADATA,
- pygrpc_cast_metadata_array_to_pyseq(tag->request_metadata), Py_None,
- Py_None, Py_None, Py_None,
- event.success ? Py_True : Py_False);
- } else {
- result = Py_BuildValue("iOOONO", GRPC_OP_COMPLETE, tag->user_tag,
- tag->call ? (PyObject*)tag->call : Py_None, Py_None,
- pygrpc_consume_ops(tag->ops, tag->nops),
- event.success ? Py_True : Py_False);
- }
- break;
- default:
- PyErr_SetString(PyExc_ValueError,
- "unknown completion type; could not translate event");
- return NULL;
- }
- pygrpc_discard_tag(tag);
- return result;
-}
-
-int pygrpc_produce_op(PyObject *op, grpc_op *result) {
- static const int OP_TUPLE_SIZE = 6;
- static const int STATUS_TUPLE_SIZE = 2;
- static const int TYPE_INDEX = 0;
- static const int INITIAL_METADATA_INDEX = 1;
- static const int TRAILING_METADATA_INDEX = 2;
- static const int MESSAGE_INDEX = 3;
- static const int STATUS_INDEX = 4;
- static const int STATUS_CODE_INDEX = 0;
- static const int STATUS_DETAILS_INDEX = 1;
- static const int WRITE_FLAGS_INDEX = 5;
- int type;
- Py_ssize_t message_size;
- char *message;
- char *status_details;
- gpr_slice message_slice;
- grpc_op c_op;
- if (!PyTuple_Check(op)) {
- PyErr_SetString(PyExc_TypeError, "expected tuple op");
- return 0;
- }
- if (PyTuple_Size(op) != OP_TUPLE_SIZE) {
- char *buf;
- gpr_asprintf(&buf, "expected tuple op of length %d", OP_TUPLE_SIZE);
- PyErr_SetString(PyExc_ValueError, buf);
- gpr_free(buf);
- return 0;
- }
- type = PyInt_AsLong(PyTuple_GET_ITEM(op, TYPE_INDEX));
- if (PyErr_Occurred()) {
- return 0;
- }
- c_op.op = type;
- c_op.reserved = NULL;
- c_op.flags = PyInt_AsLong(PyTuple_GET_ITEM(op, WRITE_FLAGS_INDEX));
- if (PyErr_Occurred()) {
- return 0;
- }
- switch (type) {
- case GRPC_OP_SEND_INITIAL_METADATA:
- if (!pygrpc_cast_pyseq_to_send_metadata(
- PyTuple_GetItem(op, INITIAL_METADATA_INDEX),
- &c_op.data.send_initial_metadata.metadata,
- &c_op.data.send_initial_metadata.count)) {
- return 0;
- }
- break;
- case GRPC_OP_SEND_MESSAGE:
- PyString_AsStringAndSize(
- PyTuple_GET_ITEM(op, MESSAGE_INDEX), &message, &message_size);
- message_slice = gpr_slice_from_copied_buffer(message, message_size);
- c_op.data.send_message = grpc_raw_byte_buffer_create(&message_slice, 1);
- gpr_slice_unref(message_slice);
- break;
- case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
- /* Don't need to fill in any other fields. */
- break;
- case GRPC_OP_SEND_STATUS_FROM_SERVER:
- if (!pygrpc_cast_pyseq_to_send_metadata(
- PyTuple_GetItem(op, TRAILING_METADATA_INDEX),
- &c_op.data.send_status_from_server.trailing_metadata,
- &c_op.data.send_status_from_server.trailing_metadata_count)) {
- return 0;
- }
- if (!PyTuple_Check(PyTuple_GET_ITEM(op, STATUS_INDEX))) {
- char *buf;
- gpr_asprintf(&buf, "expected tuple status in op of length %d",
- STATUS_TUPLE_SIZE);
- PyErr_SetString(PyExc_ValueError, buf);
- gpr_free(buf);
- return 0;
- }
- c_op.data.send_status_from_server.status = PyInt_AsLong(
- PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_CODE_INDEX));
- status_details = PyString_AsString(
- PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_DETAILS_INDEX));
- if (PyErr_Occurred()) {
- return 0;
- }
- c_op.data.send_status_from_server.status_details =
- gpr_malloc(strlen(status_details) + 1);
- strcpy((char *)c_op.data.send_status_from_server.status_details,
- status_details);
- break;
- case GRPC_OP_RECV_INITIAL_METADATA:
- c_op.data.recv_initial_metadata = gpr_malloc(sizeof(grpc_metadata_array));
- grpc_metadata_array_init(c_op.data.recv_initial_metadata);
- break;
- case GRPC_OP_RECV_MESSAGE:
- c_op.data.recv_message = gpr_malloc(sizeof(grpc_byte_buffer *));
- break;
- case GRPC_OP_RECV_STATUS_ON_CLIENT:
- c_op.data.recv_status_on_client.trailing_metadata =
- gpr_malloc(sizeof(grpc_metadata_array));
- grpc_metadata_array_init(c_op.data.recv_status_on_client.trailing_metadata);
- c_op.data.recv_status_on_client.status =
- gpr_malloc(sizeof(grpc_status_code *));
- c_op.data.recv_status_on_client.status_details =
- gpr_malloc(sizeof(char *));
- *c_op.data.recv_status_on_client.status_details = NULL;
- c_op.data.recv_status_on_client.status_details_capacity =
- gpr_malloc(sizeof(size_t));
- *c_op.data.recv_status_on_client.status_details_capacity = 0;
- break;
- case GRPC_OP_RECV_CLOSE_ON_SERVER:
- c_op.data.recv_close_on_server.cancelled = gpr_malloc(sizeof(int));
- break;
- default:
- return 0;
- }
- *result = c_op;
- return 1;
-}
-
-void pygrpc_discard_op(grpc_op op) {
- size_t i;
- switch(op.op) {
- case GRPC_OP_SEND_INITIAL_METADATA:
- /* Whenever we produce send-metadata, we allocate new strings (to handle
- arbitrary sequence input as opposed to just lists or just tuples). We
- thus must free those elements. */
- for (i = 0; i < op.data.send_initial_metadata.count; ++i) {
- gpr_free((void *)op.data.send_initial_metadata.metadata[i].key);
- gpr_free((void *)op.data.send_initial_metadata.metadata[i].value);
- }
- gpr_free(op.data.send_initial_metadata.metadata);
- break;
- case GRPC_OP_SEND_MESSAGE:
- grpc_byte_buffer_destroy(op.data.send_message);
- break;
- case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
- /* Don't need to free any fields. */
- break;
- case GRPC_OP_SEND_STATUS_FROM_SERVER:
- /* Whenever we produce send-metadata, we allocate new strings (to handle
- arbitrary sequence input as opposed to just lists or just tuples). We
- thus must free those elements. */
- for (i = 0; i < op.data.send_status_from_server.trailing_metadata_count;
- ++i) {
- gpr_free(
- (void *)op.data.send_status_from_server.trailing_metadata[i].key);
- gpr_free(
- (void *)op.data.send_status_from_server.trailing_metadata[i].value);
- }
- gpr_free(op.data.send_status_from_server.trailing_metadata);
- gpr_free((char *)op.data.send_status_from_server.status_details);
- break;
- case GRPC_OP_RECV_INITIAL_METADATA:
- grpc_metadata_array_destroy(op.data.recv_initial_metadata);
- gpr_free(op.data.recv_initial_metadata);
- break;
- case GRPC_OP_RECV_MESSAGE:
- grpc_byte_buffer_destroy(*op.data.recv_message);
- gpr_free(op.data.recv_message);
- break;
- case GRPC_OP_RECV_STATUS_ON_CLIENT:
- grpc_metadata_array_destroy(op.data.recv_status_on_client.trailing_metadata);
- gpr_free(op.data.recv_status_on_client.trailing_metadata);
- gpr_free(op.data.recv_status_on_client.status);
- gpr_free(*op.data.recv_status_on_client.status_details);
- gpr_free(op.data.recv_status_on_client.status_details);
- gpr_free(op.data.recv_status_on_client.status_details_capacity);
- break;
- case GRPC_OP_RECV_CLOSE_ON_SERVER:
- gpr_free(op.data.recv_close_on_server.cancelled);
- break;
- }
-}
-
-PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops) {
- static const int TYPE_INDEX = 0;
- static const int INITIAL_METADATA_INDEX = 1;
- static const int TRAILING_METADATA_INDEX = 2;
- static const int MESSAGE_INDEX = 3;
- static const int STATUS_INDEX = 4;
- static const int CANCELLED_INDEX = 5;
- static const int OPRESULT_LENGTH = 6;
- PyObject *list;
- size_t i;
- size_t j;
- char *bytes;
- size_t bytes_size;
- PyObject *results = PyList_New(nops);
- if (!results) {
- return NULL;
- }
- for (i = 0; i < nops; ++i) {
- PyObject *result = PyTuple_Pack(OPRESULT_LENGTH, Py_None, Py_None, Py_None,
- Py_None, Py_None, Py_None);
- PyTuple_SetItem(result, TYPE_INDEX, PyInt_FromLong(op[i].op));
- switch(op[i].op) {
- case GRPC_OP_RECV_INITIAL_METADATA:
- PyTuple_SetItem(result, INITIAL_METADATA_INDEX,
- list=PyList_New(op[i].data.recv_initial_metadata->count));
- for (j = 0; j < op[i].data.recv_initial_metadata->count; ++j) {
- grpc_metadata md = op[i].data.recv_initial_metadata->metadata[j];
- PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value,
- (Py_ssize_t)md.value_length));
- }
- break;
- case GRPC_OP_RECV_MESSAGE:
- if (*op[i].data.recv_message) {
- pygrpc_byte_buffer_to_bytes(
- *op[i].data.recv_message, &bytes, &bytes_size);
- PyTuple_SetItem(result, MESSAGE_INDEX,
- PyString_FromStringAndSize(bytes, bytes_size));
- gpr_free(bytes);
- } else {
- PyTuple_SetItem(result, MESSAGE_INDEX, Py_BuildValue(""));
- }
- break;
- case GRPC_OP_RECV_STATUS_ON_CLIENT:
- PyTuple_SetItem(
- result, TRAILING_METADATA_INDEX,
- list = PyList_New(op[i].data.recv_status_on_client.trailing_metadata->count));
- for (j = 0; j < op[i].data.recv_status_on_client.trailing_metadata->count; ++j) {
- grpc_metadata md =
- op[i].data.recv_status_on_client.trailing_metadata->metadata[j];
- PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value,
- (Py_ssize_t)md.value_length));
- }
- PyTuple_SetItem(
- result, STATUS_INDEX, Py_BuildValue(
- "is", *op[i].data.recv_status_on_client.status,
- *op[i].data.recv_status_on_client.status_details));
- break;
- case GRPC_OP_RECV_CLOSE_ON_SERVER:
- PyTuple_SetItem(
- result, CANCELLED_INDEX,
- PyBool_FromLong(*op[i].data.recv_close_on_server.cancelled));
- break;
- default:
- break;
- }
- pygrpc_discard_op(op[i]);
- PyList_SetItem(results, i, result);
- }
- return results;
-}
-
-double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec) {
- timespec = gpr_convert_clock_type(timespec, GPR_CLOCK_REALTIME);
- return timespec.tv_sec + 1e-9*timespec.tv_nsec;
-}
-
-/* Because C89 doesn't have a way to check for infinity... */
-static int pygrpc_isinf(double x) {
- return x * 0 != 0;
-}
-
-gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds) {
- gpr_timespec result;
- if (pygrpc_isinf(seconds)) {
- result = seconds > 0.0 ? gpr_inf_future(GPR_CLOCK_REALTIME)
- : gpr_inf_past(GPR_CLOCK_REALTIME);
- } else {
- result.tv_sec = (time_t)seconds;
- result.tv_nsec = ((seconds - result.tv_sec) * 1e9);
- result.clock_type = GPR_CLOCK_REALTIME;
- }
- return result;
-}
-
-int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args) {
- size_t num_args = PyList_Size(py_args);
- size_t i;
- grpc_channel_args args;
- args.num_args = num_args;
- args.args = gpr_malloc(sizeof(grpc_arg) * num_args);
- for (i = 0; i < args.num_args; ++i) {
- char *key;
- PyObject *value;
- if (!PyArg_ParseTuple(PyList_GetItem(py_args, i), "zO", &key, &value)) {
- gpr_free(args.args);
- args.num_args = 0;
- args.args = NULL;
- PyErr_SetString(PyExc_TypeError,
- "expected a list of 2-tuple of str and str|int|None");
- return 0;
- }
- args.args[i].key = key;
- if (PyInt_Check(value)) {
- args.args[i].type = GRPC_ARG_INTEGER;
- args.args[i].value.integer = PyInt_AsLong(value);
- } else if (PyString_Check(value)) {
- args.args[i].type = GRPC_ARG_STRING;
- args.args[i].value.string = PyString_AsString(value);
- } else if (value == Py_None) {
- --args.num_args;
- --i;
- continue;
- } else {
- gpr_free(args.args);
- args.num_args = 0;
- args.args = NULL;
- PyErr_SetString(PyExc_TypeError,
- "expected a list of 2-tuple of str and str|int|None");
- return 0;
- }
- }
- *c_args = args;
- return 1;
-}
-
-void pygrpc_discard_channel_args(grpc_channel_args args) {
- gpr_free(args.args);
-}
-
-int pygrpc_cast_pyseq_to_send_metadata(
- PyObject *pyseq, grpc_metadata **metadata, size_t *count) {
- size_t i;
- Py_ssize_t value_length;
- char *key;
- char *value;
- if (!PySequence_Check(pyseq)) {
- return 0;
- }
- *count = PySequence_Size(pyseq);
- *metadata = gpr_malloc(sizeof(grpc_metadata) * *count);
- for (i = 0; i < *count; ++i) {
- PyObject *item = PySequence_GetItem(pyseq, i);
- if (!PyArg_ParseTuple(item, "ss#", &key, &value, &value_length)) {
- Py_DECREF(item);
- gpr_free(*metadata);
- *count = 0;
- *metadata = NULL;
- return 0;
- } else {
- (*metadata)[i].key = gpr_strdup(key);
- (*metadata)[i].value = gpr_malloc(value_length);
- memcpy((void *)(*metadata)[i].value, value, value_length);
- Py_DECREF(item);
- }
- (*metadata)[i].value_length = value_length;
- }
- return 1;
-}
-
-PyObject *pygrpc_cast_metadata_array_to_pyseq(grpc_metadata_array metadata) {
- PyObject *result = PyTuple_New(metadata.count);
- size_t i;
- for (i = 0; i < metadata.count; ++i) {
- PyTuple_SetItem(
- result, i, Py_BuildValue(
- "ss#", metadata.metadata[i].key, metadata.metadata[i].value,
- (Py_ssize_t)metadata.metadata[i].value_length));
- if (PyErr_Occurred()) {
- Py_DECREF(result);
- return NULL;
- }
- }
- return result;
-}
-
-void pygrpc_byte_buffer_to_bytes(
- grpc_byte_buffer *buffer, char **result, size_t *result_size) {
- grpc_byte_buffer_reader reader;
- gpr_slice slice;
- char *read_result = NULL;
- size_t size = 0;
- grpc_byte_buffer_reader_init(&reader, buffer);
- while (grpc_byte_buffer_reader_next(&reader, &slice)) {
- read_result = gpr_realloc(read_result, size + GPR_SLICE_LENGTH(slice));
- memcpy(read_result + size, GPR_SLICE_START_PTR(slice),
- GPR_SLICE_LENGTH(slice));
- size = size + GPR_SLICE_LENGTH(slice);
- gpr_slice_unref(slice);
- }
- *result_size = size;
- *result = read_result;
-}
diff --git a/src/python/grpcio/tests/unit/_adapter/_c_test.py b/src/python/grpcio/grpc/_adapter/_implementations.py
similarity index 74%
rename from src/python/grpcio/tests/unit/_adapter/_c_test.py
rename to src/python/grpcio/grpc/_adapter/_implementations.py
index fe020e2a9cf..b85f228bf69 100644
--- a/src/python/grpcio/tests/unit/_adapter/_c_test.py
+++ b/src/python/grpcio/grpc/_adapter/_implementations.py
@@ -27,29 +27,22 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-import time
-import unittest
+import collections
-from grpc._adapter import _c
-from grpc._adapter import _types
+from grpc.beta import interfaces
+class AuthMetadataContext(collections.namedtuple(
+ 'AuthMetadataContext', [
+ 'service_url',
+ 'method_name'
+ ]), interfaces.GRPCAuthMetadataContext):
+ pass
-class CTypeSmokeTest(unittest.TestCase):
- def testCompletionQueueUpDown(self):
- completion_queue = _c.CompletionQueue()
- del completion_queue
+class AuthMetadataPluginCallback(interfaces.GRPCAuthMetadataContext):
- def testServerUpDown(self):
- completion_queue = _c.CompletionQueue()
- serv = _c.Server(completion_queue, [])
- del serv
- del completion_queue
+ def __init__(self, callback):
+ self._callback = callback
- def testChannelUpDown(self):
- channel = _c.Channel('[::]:0', [])
- del channel
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
+ def __call__(self, metadata, error):
+ self._callback(metadata, error)
diff --git a/src/python/grpcio/grpc/_adapter/_intermediary_low.py b/src/python/grpcio/grpc/_adapter/_intermediary_low.py
index 5634c2024d3..9698ffeabf1 100644
--- a/src/python/grpcio/grpc/_adapter/_intermediary_low.py
+++ b/src/python/grpcio/grpc/_adapter/_intermediary_low.py
@@ -115,16 +115,20 @@ class Call(object):
return call
def invoke(self, completion_queue, metadata_tag, finish_tag):
- err0 = self._internal.start_batch([
+ err = self._internal.start_batch([
_types.OpArgs.send_initial_metadata(self._metadata)
], _IGNORE_ME_TAG)
- err1 = self._internal.start_batch([
+ if err != _types.CallError.OK:
+ return err
+ err = self._internal.start_batch([
_types.OpArgs.recv_initial_metadata()
], _TagAdapter(metadata_tag, Event.Kind.METADATA_ACCEPTED))
- err2 = self._internal.start_batch([
+ if err != _types.CallError.OK:
+ return err
+ err = self._internal.start_batch([
_types.OpArgs.recv_status_on_client()
], _TagAdapter(finish_tag, Event.Kind.FINISH))
- return err0 if err0 != _types.CallError.OK else err1 if err1 != _types.CallError.OK else err2 if err2 != _types.CallError.OK else _types.CallError.OK
+ return err
def write(self, message, tag, flags):
return self._internal.start_batch([
@@ -158,7 +162,8 @@ class Call(object):
def status(self, status, tag):
return self._internal.start_batch([
- _types.OpArgs.send_status_from_server(self._metadata, status.code, status.details)
+ _types.OpArgs.send_status_from_server(
+ self._metadata, status.code, status.details)
], _TagAdapter(tag, Event.Kind.COMPLETE_ACCEPTED))
def cancel(self):
@@ -168,20 +173,17 @@ class Call(object):
return self._internal.peer()
def set_credentials(self, creds):
- return self._internal.set_credentials(creds._internal)
+ return self._internal.set_credentials(creds)
class Channel(object):
"""Adapter from old _low.Channel interface to new _low.Channel."""
- def __init__(self, hostport, client_credentials, server_host_override=None):
+ def __init__(self, hostport, channel_credentials, server_host_override=None):
args = []
if server_host_override:
args.append((_types.GrpcChannelArgumentKeys.SSL_TARGET_NAME_OVERRIDE.value, server_host_override))
- creds = None
- if client_credentials:
- creds = client_credentials._internal
- self._internal = _low.Channel(hostport, args, creds)
+ self._internal = _low.Channel(hostport, args, channel_credentials)
class CompletionQueue(object):
@@ -192,7 +194,7 @@ class CompletionQueue(object):
def get(self, deadline=None):
if deadline is None:
- ev = self._internal.next()
+ ev = self._internal.next(float('+inf'))
else:
ev = self._internal.next(deadline)
if ev is None:
@@ -240,7 +242,7 @@ class Server(object):
if server_credentials is None:
return self._internal.add_http2_port(addr, None)
else:
- return self._internal.add_http2_port(addr, server_credentials._internal)
+ return self._internal.add_http2_port(addr, server_credentials)
def start(self):
return self._internal.start()
@@ -248,20 +250,9 @@ class Server(object):
def service(self, tag):
return self._internal.request_call(self._internal_cq, _TagAdapter(tag, Event.Kind.SERVICE_ACCEPTED))
+ def cancel_all_calls(self):
+ self._internal.cancel_all_calls()
+
def stop(self):
return self._internal.shutdown(_TagAdapter(None, Event.Kind.STOP))
-
-class ClientCredentials(object):
- """Adapter from old _low.ClientCredentials interface to new _low.ChannelCredentials."""
-
- def __init__(self, root_certificates, private_key, certificate_chain):
- self._internal = _low.ChannelCredentials.ssl(root_certificates, private_key, certificate_chain)
-
-
-class ServerCredentials(object):
- """Adapter from old _low.ServerCredentials interface to new _low.ServerCredentials."""
-
- def __init__(self, root_credentials, pair_sequence, force_client_auth):
- self._internal = _low.ServerCredentials.ssl(
- root_credentials, list(pair_sequence), force_client_auth)
diff --git a/src/python/grpcio/grpc/_adapter/_low.py b/src/python/grpcio/grpc/_adapter/_low.py
index 57146aaefe8..b13d8dd9dda 100644
--- a/src/python/grpcio/grpc/_adapter/_low.py
+++ b/src/python/grpcio/grpc/_adapter/_low.py
@@ -27,36 +27,157 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import threading
+
from grpc import _grpcio_metadata
-from grpc._adapter import _c
+from grpc._cython import cygrpc
+from grpc._adapter import _implementations
from grpc._adapter import _types
_USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
-ChannelCredentials = _c.ChannelCredentials
-CallCredentials = _c.CallCredentials
-ServerCredentials = _c.ServerCredentials
+ChannelCredentials = cygrpc.ChannelCredentials
+CallCredentials = cygrpc.CallCredentials
+ServerCredentials = cygrpc.ServerCredentials
+
+channel_credentials_composite = cygrpc.channel_credentials_composite
+call_credentials_composite = cygrpc.call_credentials_composite
+
+def server_credentials_ssl(root_credentials, pair_sequence, force_client_auth):
+ return cygrpc.server_credentials_ssl(
+ root_credentials,
+ [cygrpc.SslPemKeyCertPair(key, pem) for key, pem in pair_sequence],
+ force_client_auth)
+
+def channel_credentials_ssl(
+ root_certificates, private_key, certificate_chain):
+ pair = None
+ if private_key is not None or certificate_chain is not None:
+ pair = cygrpc.SslPemKeyCertPair(private_key, certificate_chain)
+ return cygrpc.channel_credentials_ssl(root_certificates, pair)
+
+
+class _WrappedCygrpcCallback(object):
+
+ def __init__(self, cygrpc_callback):
+ self.is_called = False
+ self.error = None
+ self.is_called_lock = threading.Lock()
+ self.cygrpc_callback = cygrpc_callback
+
+ def _invoke_failure(self, error):
+ # TODO(atash) translate different Exception superclasses into different
+ # status codes.
+ self.cygrpc_callback(
+ cygrpc.Metadata([]), cygrpc.StatusCode.internal, error.message)
+
+ def _invoke_success(self, metadata):
+ try:
+ cygrpc_metadata = cygrpc.Metadata(
+ cygrpc.Metadatum(key, value)
+ for key, value in metadata)
+ except Exception as error:
+ self._invoke_failure(error)
+ return
+ self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, '')
+
+ def __call__(self, metadata, error):
+ with self.is_called_lock:
+ if self.is_called:
+ raise RuntimeError('callback should only ever be invoked once')
+ if self.error:
+ self._invoke_failure(self.error)
+ return
+ self.is_called = True
+ if error is None:
+ self._invoke_success(metadata)
+ else:
+ self._invoke_failure(error)
+
+ def notify_failure(self, error):
+ with self.is_called_lock:
+ if not self.is_called:
+ self.error = error
+
+
+class _WrappedPlugin(object):
+
+ def __init__(self, plugin):
+ self.plugin = plugin
+
+ def __call__(self, context, cygrpc_callback):
+ wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
+ wrapped_context = _implementations.AuthMetadataContext(context.service_url,
+ context.method_name)
+ try:
+ self.plugin(
+ wrapped_context,
+ _implementations.AuthMetadataPluginCallback(wrapped_cygrpc_callback))
+ except Exception as error:
+ wrapped_cygrpc_callback.notify_failure(error)
+ raise
+
+
+def call_credentials_metadata_plugin(plugin, name):
+ """
+ Args:
+ plugin: A callable accepting a _types.AuthMetadataContext
+ object and a callback (itself accepting a list of metadata key/value
+ 2-tuples and a None-able exception value). The callback must be eventually
+ called, but need not be called in plugin's invocation.
+ plugin's invocation must be non-blocking.
+ """
+ return cygrpc.call_credentials_metadata_plugin(
+ cygrpc.CredentialsMetadataPlugin(_WrappedPlugin(plugin), name))
class CompletionQueue(_types.CompletionQueue):
def __init__(self):
- self.completion_queue = _c.CompletionQueue()
+ self.completion_queue = cygrpc.CompletionQueue()
def next(self, deadline=float('+inf')):
- raw_event = self.completion_queue.next(deadline)
- if raw_event is None:
+ raw_event = self.completion_queue.poll(cygrpc.Timespec(deadline))
+ if raw_event.type == cygrpc.CompletionType.queue_timeout:
return None
- event = _types.Event(*raw_event)
- if event.call is not None:
- event = event._replace(call=Call(event.call))
- if event.call_details is not None:
- event = event._replace(call_details=_types.CallDetails(*event.call_details))
- if event.results is not None:
- new_results = [_types.OpResult(*r) for r in event.results]
- new_results = [r if r.status is None else r._replace(status=_types.Status(_types.StatusCode(r.status[0]), r.status[1])) for r in new_results]
- event = event._replace(results=new_results)
- return event
+ event_type = raw_event.type
+ event_tag = raw_event.tag
+ event_call = Call(raw_event.operation_call)
+ if raw_event.request_call_details:
+ event_call_details = _types.CallDetails(
+ raw_event.request_call_details.method,
+ raw_event.request_call_details.host,
+ float(raw_event.request_call_details.deadline))
+ else:
+ event_call_details = None
+ event_success = raw_event.success
+ event_results = []
+ if raw_event.is_new_request:
+ event_results.append(_types.OpResult(
+ _types.OpType.RECV_INITIAL_METADATA, raw_event.request_metadata,
+ None, None, None, None))
+ else:
+ if raw_event.batch_operations:
+ for operation in raw_event.batch_operations:
+ result_type = operation.type
+ result_initial_metadata = operation.received_metadata_or_none
+ result_trailing_metadata = operation.received_metadata_or_none
+ result_message = operation.received_message_or_none
+ if result_message is not None:
+ result_message = result_message.bytes()
+ result_cancelled = operation.received_cancelled_or_none
+ if operation.has_status:
+ result_status = _types.Status(
+ operation.received_status_code_or_none,
+ operation.received_status_details_or_none)
+ else:
+ result_status = None
+ event_results.append(
+ _types.OpResult(result_type, result_initial_metadata,
+ result_trailing_metadata, result_message,
+ result_status, result_cancelled))
+ return _types.Event(event_type, event_tag, event_call, event_call_details,
+ event_results, event_success)
def shutdown(self):
self.completion_queue.shutdown()
@@ -68,7 +189,36 @@ class Call(_types.Call):
self.call = call
def start_batch(self, ops, tag):
- return self.call.start_batch(ops, tag)
+ translated_ops = []
+ for op in ops:
+ if op.type == _types.OpType.SEND_INITIAL_METADATA:
+ translated_op = cygrpc.operation_send_initial_metadata(
+ cygrpc.Metadata(
+ cygrpc.Metadatum(key, value)
+ for key, value in op.initial_metadata))
+ elif op.type == _types.OpType.SEND_MESSAGE:
+ translated_op = cygrpc.operation_send_message(op.message)
+ elif op.type == _types.OpType.SEND_CLOSE_FROM_CLIENT:
+ translated_op = cygrpc.operation_send_close_from_client()
+ elif op.type == _types.OpType.SEND_STATUS_FROM_SERVER:
+ translated_op = cygrpc.operation_send_status_from_server(
+ cygrpc.Metadata(
+ cygrpc.Metadatum(key, value)
+ for key, value in op.trailing_metadata),
+ op.status.code,
+ op.status.details)
+ elif op.type == _types.OpType.RECV_INITIAL_METADATA:
+ translated_op = cygrpc.operation_receive_initial_metadata()
+ elif op.type == _types.OpType.RECV_MESSAGE:
+ translated_op = cygrpc.operation_receive_message()
+ elif op.type == _types.OpType.RECV_STATUS_ON_CLIENT:
+ translated_op = cygrpc.operation_receive_status_on_client()
+ elif op.type == _types.OpType.RECV_CLOSE_ON_SERVER:
+ translated_op = cygrpc.operation_receive_close_on_server()
+ else:
+ raise ValueError('unexpected operation type {}'.format(op.type))
+ translated_ops.append(translated_op)
+ return self.call.start_batch(cygrpc.Operations(translated_ops), tag)
def cancel(self, code=None, details=None):
if code is None and details is None:
@@ -86,14 +236,20 @@ class Call(_types.Call):
class Channel(_types.Channel):
def __init__(self, target, args, creds=None):
- args = list(args) + [(_c.PRIMARY_USER_AGENT_KEY, _USER_AGENT)]
+ args = list(args) + [
+ (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)]
+ args = cygrpc.ChannelArgs(
+ cygrpc.ChannelArg(key, value) for key, value in args)
if creds is None:
- self.channel = _c.Channel(target, args)
+ self.channel = cygrpc.Channel(target, args)
else:
- self.channel = _c.Channel(target, args, creds)
+ self.channel = cygrpc.Channel(target, args, creds)
def create_call(self, completion_queue, method, host, deadline=None):
- return Call(self.channel.create_call(completion_queue.completion_queue, method, host, deadline))
+ internal_call = self.channel.create_call(
+ None, 0, completion_queue.completion_queue, method, host,
+ cygrpc.Timespec(deadline))
+ return Call(internal_call)
def check_connectivity_state(self, try_to_connect):
return self.channel.check_connectivity_state(try_to_connect)
@@ -101,7 +257,8 @@ class Channel(_types.Channel):
def watch_connectivity_state(self, last_observed_state, deadline,
completion_queue, tag):
self.channel.watch_connectivity_state(
- last_observed_state, deadline, completion_queue.completion_queue, tag)
+ last_observed_state, cygrpc.Timespec(deadline),
+ completion_queue.completion_queue, tag)
def target(self):
return self.channel.target()
@@ -112,7 +269,11 @@ _NO_TAG = object()
class Server(_types.Server):
def __init__(self, completion_queue, args):
- self.server = _c.Server(completion_queue.completion_queue, args)
+ args = cygrpc.ChannelArgs(
+ cygrpc.ChannelArg(key, value) for key, value in args)
+ self.server = cygrpc.Server(args)
+ self.server.register_completion_queue(completion_queue.completion_queue)
+ self.server_queue = completion_queue
def add_http2_port(self, addr, creds=None):
if creds is None:
@@ -124,10 +285,11 @@ class Server(_types.Server):
return self.server.start()
def shutdown(self, tag=None):
- return self.server.shutdown(tag)
+ return self.server.shutdown(self.server_queue.completion_queue, tag)
def request_call(self, completion_queue, tag):
- return self.server.request_call(completion_queue.completion_queue, tag)
+ return self.server.request_call(completion_queue.completion_queue,
+ self.server_queue.completion_queue, tag)
def cancel_all_calls(self):
return self.server.cancel_all_calls()
diff --git a/src/python/grpcio/grpc/_adapter/_types.py b/src/python/grpcio/grpc/_adapter/_types.py
index ca0fa066bc8..3d5ab33d008 100644
--- a/src/python/grpcio/grpc/_adapter/_types.py
+++ b/src/python/grpcio/grpc/_adapter/_types.py
@@ -31,6 +31,8 @@ import abc
import collections
import enum
+from grpc._cython import cygrpc
+
class GrpcChannelArgumentKeys(enum.Enum):
"""Mirrors keys used in grpc_channel_args for GRPC-specific arguments."""
@@ -40,77 +42,77 @@ class GrpcChannelArgumentKeys(enum.Enum):
@enum.unique
class CallError(enum.IntEnum):
"""Mirrors grpc_call_error in the C core."""
- OK = 0
- ERROR = 1
- ERROR_NOT_ON_SERVER = 2
- ERROR_NOT_ON_CLIENT = 3
- ERROR_ALREADY_ACCEPTED = 4
- ERROR_ALREADY_INVOKED = 5
- ERROR_NOT_INVOKED = 6
- ERROR_ALREADY_FINISHED = 7
- ERROR_TOO_MANY_OPERATIONS = 8
- ERROR_INVALID_FLAGS = 9
- ERROR_INVALID_METADATA = 10
+ OK = cygrpc.CallError.ok
+ ERROR = cygrpc.CallError.error
+ ERROR_NOT_ON_SERVER = cygrpc.CallError.not_on_server
+ ERROR_NOT_ON_CLIENT = cygrpc.CallError.not_on_client
+ ERROR_ALREADY_ACCEPTED = cygrpc.CallError.already_accepted
+ ERROR_ALREADY_INVOKED = cygrpc.CallError.already_invoked
+ ERROR_NOT_INVOKED = cygrpc.CallError.not_invoked
+ ERROR_ALREADY_FINISHED = cygrpc.CallError.already_finished
+ ERROR_TOO_MANY_OPERATIONS = cygrpc.CallError.too_many_operations
+ ERROR_INVALID_FLAGS = cygrpc.CallError.invalid_flags
+ ERROR_INVALID_METADATA = cygrpc.CallError.invalid_metadata
@enum.unique
class StatusCode(enum.IntEnum):
"""Mirrors grpc_status_code in the C core."""
- OK = 0
- CANCELLED = 1
- UNKNOWN = 2
- INVALID_ARGUMENT = 3
- DEADLINE_EXCEEDED = 4
- NOT_FOUND = 5
- ALREADY_EXISTS = 6
- PERMISSION_DENIED = 7
- RESOURCE_EXHAUSTED = 8
- FAILED_PRECONDITION = 9
- ABORTED = 10
- OUT_OF_RANGE = 11
- UNIMPLEMENTED = 12
- INTERNAL = 13
- UNAVAILABLE = 14
- DATA_LOSS = 15
- UNAUTHENTICATED = 16
+ OK = cygrpc.StatusCode.ok
+ CANCELLED = cygrpc.StatusCode.cancelled
+ UNKNOWN = cygrpc.StatusCode.unknown
+ INVALID_ARGUMENT = cygrpc.StatusCode.invalid_argument
+ DEADLINE_EXCEEDED = cygrpc.StatusCode.deadline_exceeded
+ NOT_FOUND = cygrpc.StatusCode.not_found
+ ALREADY_EXISTS = cygrpc.StatusCode.already_exists
+ PERMISSION_DENIED = cygrpc.StatusCode.permission_denied
+ RESOURCE_EXHAUSTED = cygrpc.StatusCode.resource_exhausted
+ FAILED_PRECONDITION = cygrpc.StatusCode.failed_precondition
+ ABORTED = cygrpc.StatusCode.aborted
+ OUT_OF_RANGE = cygrpc.StatusCode.out_of_range
+ UNIMPLEMENTED = cygrpc.StatusCode.unimplemented
+ INTERNAL = cygrpc.StatusCode.internal
+ UNAVAILABLE = cygrpc.StatusCode.unavailable
+ DATA_LOSS = cygrpc.StatusCode.data_loss
+ UNAUTHENTICATED = cygrpc.StatusCode.unauthenticated
@enum.unique
class OpWriteFlags(enum.IntEnum):
"""Mirrors defined write-flag constants in the C core."""
- WRITE_BUFFER_HINT = 1
- WRITE_NO_COMPRESS = 2
+ WRITE_BUFFER_HINT = cygrpc.WriteFlag.buffer_hint
+ WRITE_NO_COMPRESS = cygrpc.WriteFlag.no_compress
@enum.unique
class OpType(enum.IntEnum):
"""Mirrors grpc_op_type in the C core."""
- SEND_INITIAL_METADATA = 0
- SEND_MESSAGE = 1
- SEND_CLOSE_FROM_CLIENT = 2
- SEND_STATUS_FROM_SERVER = 3
- RECV_INITIAL_METADATA = 4
- RECV_MESSAGE = 5
- RECV_STATUS_ON_CLIENT = 6
- RECV_CLOSE_ON_SERVER = 7
+ SEND_INITIAL_METADATA = cygrpc.OperationType.send_initial_metadata
+ SEND_MESSAGE = cygrpc.OperationType.send_message
+ SEND_CLOSE_FROM_CLIENT = cygrpc.OperationType.send_close_from_client
+ SEND_STATUS_FROM_SERVER = cygrpc.OperationType.send_status_from_server
+ RECV_INITIAL_METADATA = cygrpc.OperationType.receive_initial_metadata
+ RECV_MESSAGE = cygrpc.OperationType.receive_message
+ RECV_STATUS_ON_CLIENT = cygrpc.OperationType.receive_status_on_client
+ RECV_CLOSE_ON_SERVER = cygrpc.OperationType.receive_close_on_server
@enum.unique
class EventType(enum.IntEnum):
"""Mirrors grpc_completion_type in the C core."""
- QUEUE_SHUTDOWN = 0
- QUEUE_TIMEOUT = 1 # if seen on the Python side, something went horridly wrong
- OP_COMPLETE = 2
+ QUEUE_SHUTDOWN = cygrpc.CompletionType.queue_shutdown
+ QUEUE_TIMEOUT = cygrpc.CompletionType.queue_timeout
+ OP_COMPLETE = cygrpc.CompletionType.operation_complete
@enum.unique
class ConnectivityState(enum.IntEnum):
"""Mirrors grpc_connectivity_state in the C core."""
- IDLE = 0
- CONNECTING = 1
- READY = 2
- TRANSIENT_FAILURE = 3
- FATAL_FAILURE = 4
+ IDLE = cygrpc.ConnectivityState.idle
+ CONNECTING = cygrpc.ConnectivityState.connecting
+ READY = cygrpc.ConnectivityState.ready
+ TRANSIENT_FAILURE = cygrpc.ConnectivityState.transient_failure
+ FATAL_FAILURE = cygrpc.ConnectivityState.fatal_failure
class Status(collections.namedtuple(
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx
index 51c46681388..1c07f9f4f4c 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx
@@ -53,24 +53,24 @@ cdef class Call:
self.c_call, cy_operations.c_ops, cy_operations.c_nops,
operation_tag, NULL)
- def cancel(self,
- grpc.grpc_status_code error_code=grpc.GRPC_STATUS__DO_NOT_USE,
- details=None):
+ def cancel(
+ self, grpc.grpc_status_code error_code=grpc.GRPC_STATUS__DO_NOT_USE,
+ details=None):
if not self.is_valid:
raise ValueError("invalid call object cannot be used from Python")
if (details is None) != (error_code == grpc.GRPC_STATUS__DO_NOT_USE):
raise ValueError("if error_code is specified, so must details "
"(and vice-versa)")
- if isinstance(details, bytes):
- pass
- elif isinstance(details, basestring):
- details = details.encode()
- else:
- raise TypeError("expected details to be str or bytes")
if error_code != grpc.GRPC_STATUS__DO_NOT_USE:
+ if isinstance(details, bytes):
+ pass
+ elif isinstance(details, basestring):
+ details = details.encode()
+ else:
+ raise TypeError("expected details to be str or bytes")
self.references.append(details)
- return grpc.grpc_call_cancel_with_status(self.c_call, error_code, details,
- NULL)
+ return grpc.grpc_call_cancel_with_status(
+ self.c_call, error_code, details, NULL)
else:
return grpc.grpc_call_cancel(self.c_call, NULL)
@@ -79,6 +79,12 @@ cdef class Call:
return grpc.grpc_call_set_credentials(
self.c_call, call_credentials.c_credentials)
+ def peer(self):
+ cdef char *peer = grpc.grpc_call_get_peer(self.c_call)
+ result = peer
+ grpc.gpr_free(peer)
+ return result
+
def __dealloc__(self):
if self.c_call != NULL:
grpc.grpc_call_destroy(self.c_call)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx
index e25db3e2a44..a944a83576c 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx
@@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+cimport cpython
+
from grpc._cython._cygrpc cimport call
from grpc._cython._cygrpc cimport completion_queue
from grpc._cython._cygrpc cimport credentials
@@ -70,12 +72,16 @@ cdef class Channel:
method = method.encode()
else:
raise TypeError("expected method to be str or bytes")
- if isinstance(host, bytes):
+ cdef char *host_c_string = NULL
+ if host is None:
pass
+ elif isinstance(host, bytes):
+ host_c_string = host
elif isinstance(host, basestring):
host = host.encode()
+ host_c_string = host
else:
- raise TypeError("expected host to be str or bytes")
+ raise TypeError("expected host to be str, bytes, or None")
cdef call.Call operation_call = call.Call()
operation_call.references = [self, method, host, queue]
cdef grpc.grpc_call *parent_call = NULL
@@ -83,10 +89,29 @@ cdef class Channel:
parent_call = parent.c_call
operation_call.c_call = grpc.grpc_channel_create_call(
self.c_channel, parent_call, flags,
- queue.c_completion_queue, method, host, deadline.c_time,
+ queue.c_completion_queue, method, host_c_string, deadline.c_time,
NULL)
return operation_call
+ def check_connectivity_state(self, bint try_to_connect):
+ return grpc.grpc_channel_check_connectivity_state(self.c_channel,
+ try_to_connect)
+
+ def watch_connectivity_state(
+ self, last_observed_state, records.Timespec deadline not None,
+ completion_queue.CompletionQueue queue not None, tag):
+ cdef records.OperationTag operation_tag = records.OperationTag(tag)
+ cpython.Py_INCREF(operation_tag)
+ grpc.grpc_channel_watch_connectivity_state(
+ self.c_channel, last_observed_state, deadline.c_time,
+ queue.c_completion_queue, operation_tag)
+
+ def target(self):
+ cdef char * target = grpc.grpc_channel_get_target(self.c_channel)
+ result = target
+ grpc.gpr_free(target)
+ return result
+
def __dealloc__(self):
if self.c_channel != NULL:
grpc.grpc_channel_destroy(self.c_channel)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx
index a7a265eab7d..2cf49707b48 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx
@@ -62,6 +62,8 @@ cdef class CompletionQueue:
cdef grpc.grpc_event event
# Poll within a critical section
+ # TODO consider making queue polling contention a hard error to enable
+ # easier bug discovery
with self.poll_condition:
while self.is_polling:
self.poll_condition.wait(float(deadline) - time.time())
@@ -74,10 +76,12 @@ cdef class CompletionQueue:
self.poll_condition.notify()
if event.type == grpc.GRPC_QUEUE_TIMEOUT:
- return records.Event(event.type, False, None, None, None, None, None)
+ return records.Event(
+ event.type, False, None, None, None, None, False, None)
elif event.type == grpc.GRPC_QUEUE_SHUTDOWN:
self.is_shutdown = True
- return records.Event(event.type, True, None, None, None, None, None)
+ return records.Event(
+ event.type, True, None, None, None, None, False, None)
else:
if event.tag != NULL:
tag = event.tag
@@ -97,7 +101,8 @@ cdef class CompletionQueue:
operation_call.references.extend(tag.references)
return records.Event(
event.type, event.success, user_tag, operation_call,
- request_call_details, request_metadata, batch_operations)
+ request_call_details, request_metadata, tag.is_new_request,
+ batch_operations)
def shutdown(self):
grpc.grpc_completion_queue_shutdown(self.c_completion_queue)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd
index 7a9fa7b76d0..db9f8ddec99 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd
@@ -27,7 +27,10 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+cimport cpython
+
from grpc._cython._cygrpc cimport grpc
+from grpc._cython._cygrpc cimport records
cdef class ChannelCredentials:
@@ -49,3 +52,23 @@ cdef class ServerCredentials:
cdef grpc.grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs
cdef size_t c_ssl_pem_key_cert_pairs_count
cdef list references
+
+
+cdef class CredentialsMetadataPlugin:
+
+ cdef object plugin_callback
+ cdef str plugin_name
+
+ cdef grpc.grpc_metadata_credentials_plugin make_c_plugin(self)
+
+
+cdef class AuthMetadataContext:
+
+ cdef grpc.grpc_auth_metadata_context context
+
+
+cdef void plugin_get_metadata(
+ void *state, grpc.grpc_auth_metadata_context context,
+ grpc.grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil
+
+cdef void plugin_destroy_c_plugin_state(void *state)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx
index e9836fec2cf..a968894967a 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx
@@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+cimport cpython
+
from grpc._cython._cygrpc cimport grpc
from grpc._cython._cygrpc cimport records
@@ -71,19 +73,80 @@ cdef class ServerCredentials:
def __cinit__(self):
self.c_credentials = NULL
+ self.references = []
def __dealloc__(self):
if self.c_credentials != NULL:
grpc.grpc_server_credentials_release(self.c_credentials)
+cdef class CredentialsMetadataPlugin:
+
+ def __cinit__(self, object plugin_callback, str name):
+ """
+ Args:
+ plugin_callback (callable): Callback accepting a service URL (str/bytes)
+ and callback object (accepting a records.Metadata,
+ grpc.grpc_status_code, and a str/bytes error message). This argument
+ when called should be non-blocking and eventually call the callback
+ object with the appropriate status code/details and metadata (if
+ successful).
+ name (str): Plugin name.
+ """
+ if not callable(plugin_callback):
+ raise ValueError('expected callable plugin_callback')
+ self.plugin_callback = plugin_callback
+ self.plugin_name = name
+
+ @staticmethod
+ cdef grpc.grpc_metadata_credentials_plugin make_c_plugin(self):
+ cdef grpc.grpc_metadata_credentials_plugin result
+ result.get_metadata = plugin_get_metadata
+ result.destroy = plugin_destroy_c_plugin_state
+ result.state = self
+ result.type = self.plugin_name
+ cpython.Py_INCREF(self)
+ return result
+
+
+cdef class AuthMetadataContext:
+
+ def __cinit__(self):
+ self.context.service_url = NULL
+ self.context.method_name = NULL
+
+ @property
+ def service_url(self):
+ return self.context.service_url
+
+ @property
+ def method_name(self):
+ return self.context.method_name
+
+
+cdef void plugin_get_metadata(
+ void *state, grpc.grpc_auth_metadata_context context,
+ grpc.grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil:
+ def python_callback(
+ records.Metadata metadata, grpc.grpc_status_code status,
+ const char *error_details):
+ cb(user_data, metadata.c_metadata_array.metadata,
+ metadata.c_metadata_array.count, status, error_details)
+ cdef CredentialsMetadataPlugin self = state
+ cdef AuthMetadataContext cy_context = AuthMetadataContext()
+ cy_context.context = context
+ self.plugin_callback(cy_context, python_callback)
+
+cdef void plugin_destroy_c_plugin_state(void *state):
+ cpython.Py_DECREF(state)
+
def channel_credentials_google_default():
cdef ChannelCredentials credentials = ChannelCredentials();
credentials.c_credentials = grpc.grpc_google_default_credentials_create()
return credentials
def channel_credentials_ssl(pem_root_certificates,
- records.SslPemKeyCertPair ssl_pem_key_cert_pair):
+ records.SslPemKeyCertPair ssl_pem_key_cert_pair):
if pem_root_certificates is None:
pass
elif isinstance(pem_root_certificates, bytes):
@@ -104,6 +167,7 @@ def channel_credentials_ssl(pem_root_certificates,
else:
credentials.c_credentials = grpc.grpc_ssl_credentials_create(
c_pem_root_certificates, NULL, NULL)
+ return credentials
def channel_credentials_composite(
ChannelCredentials credentials_1 not None,
@@ -135,7 +199,6 @@ def call_credentials_google_compute_engine():
grpc.grpc_google_compute_engine_credentials_create(NULL))
return credentials
-#TODO rename to something like client_credentials_service_account_jwt_access.
def call_credentials_service_account_jwt_access(
json_key, records.Timespec token_lifetime not None):
if isinstance(json_key, bytes):
@@ -184,14 +247,25 @@ def call_credentials_google_iam(authorization_token, authority_selector):
credentials.references.append(authority_selector)
return credentials
+def call_credentials_metadata_plugin(CredentialsMetadataPlugin plugin):
+ cdef CallCredentials credentials = CallCredentials()
+ credentials.c_credentials = (
+ grpc.grpc_metadata_credentials_create_from_plugin(plugin.make_c_plugin(),
+ NULL))
+ # TODO(atash): the following held reference is *probably* never necessary
+ credentials.references.append(plugin)
+ return credentials
+
def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs,
bint force_client_auth):
+ cdef char *c_pem_root_certs = NULL
if pem_root_certs is None:
pass
elif isinstance(pem_root_certs, bytes):
- pass
+ c_pem_root_certs = pem_root_certs
elif isinstance(pem_root_certs, basestring):
pem_root_certs = pem_root_certs.encode()
+ c_pem_root_certs = pem_root_certs
else:
raise TypeError("expected pem_root_certs to be str or bytes")
pem_key_cert_pairs = list(pem_key_cert_pairs)
@@ -212,7 +286,7 @@ def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs,
credentials.c_ssl_pem_key_cert_pairs[i] = (
(pem_key_cert_pairs[i]).c_pair)
credentials.c_credentials = grpc.grpc_ssl_server_credentials_create(
- pem_root_certs, credentials.c_ssl_pem_key_cert_pairs,
+ c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs,
credentials.c_ssl_pem_key_cert_pairs_count, force_client_auth, NULL)
return credentials
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
index 36aea81a6c0..10c948cd0ac 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
@@ -132,6 +132,20 @@ cdef extern from "grpc/byte_buffer.h":
cdef extern from "grpc/grpc.h":
+ const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
+ const char *GRPC_ARG_ENABLE_CENSUS
+ const char *GRPC_ARG_MAX_CONCURRENT_STREAMS
+ const char *GRPC_ARG_MAX_MESSAGE_LENGTH
+ const char *GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER
+ const char *GRPC_ARG_DEFAULT_AUTHORITY
+ const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
+ const char *GRPC_ARG_SECONDARY_USER_AGENT_STRING
+ const char *GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
+
+ const int GRPC_WRITE_BUFFER_HINT
+ const int GRPC_WRITE_NO_COMPRESS
+ const int GRPC_WRITE_USED_MASK
+
ctypedef struct grpc_completion_queue:
# We don't care about the internals (and in fact don't know them)
pass
@@ -149,9 +163,9 @@ cdef extern from "grpc/grpc.h":
pass
ctypedef enum grpc_arg_type:
- grpc_arg_string "GRPC_ARG_STRING"
- grpc_arg_integer "GRPC_ARG_INTEGER"
- grpc_arg_pointer "GRPC_ARG_POINTER"
+ GRPC_ARG_STRING
+ GRPC_ARG_INTEGER
+ GRPC_ARG_POINTER
ctypedef struct grpc_arg_value_pointer:
void *address "p"
@@ -185,6 +199,13 @@ cdef extern from "grpc/grpc.h":
GRPC_CALL_ERROR_INVALID_FLAGS
GRPC_CALL_ERROR_INVALID_METADATA
+ ctypedef enum grpc_connectivity_state:
+ GRPC_CHANNEL_IDLE
+ GRPC_CHANNEL_CONNECTING
+ GRPC_CHANNEL_READY
+ GRPC_CHANNEL_TRANSIENT_FAILURE
+ GRPC_CHANNEL_FATAL_FAILURE
+
ctypedef struct grpc_metadata:
const char *key
const char *value
@@ -279,9 +300,9 @@ cdef extern from "grpc/grpc.h":
grpc_status_code status,
const char *description,
void *reserved)
+ char *grpc_call_get_peer(grpc_call *call)
void grpc_call_destroy(grpc_call *call)
-
grpc_channel *grpc_insecure_channel_create(const char *target,
const grpc_channel_args *args,
void *reserved)
@@ -291,6 +312,12 @@ cdef extern from "grpc/grpc.h":
grpc_completion_queue *completion_queue,
const char *method, const char *host,
gpr_timespec deadline, void *reserved)
+ grpc_connectivity_state grpc_channel_check_connectivity_state(
+ grpc_channel *channel, int try_to_connect)
+ void grpc_channel_watch_connectivity_state(
+ grpc_channel *channel, grpc_connectivity_state last_observed_state,
+ gpr_timespec deadline, grpc_completion_queue *cq, void *tag)
+ char *grpc_channel_get_target(grpc_channel *channel)
void grpc_channel_destroy(grpc_channel *channel)
grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved)
@@ -367,3 +394,27 @@ cdef extern from "grpc/grpc_security.h":
grpc_call_error grpc_call_set_credentials(grpc_call *call,
grpc_call_credentials *creds)
+
+ ctypedef struct grpc_auth_context:
+ # We don't care about the internals (and in fact don't know them)
+ pass
+
+ ctypedef struct grpc_auth_metadata_context:
+ const char *service_url
+ const char *method_name
+ const grpc_auth_context *channel_auth_context
+
+ ctypedef void (*grpc_credentials_plugin_metadata_cb)(
+ void *user_data, const grpc_metadata *creds_md, size_t num_creds_md,
+ grpc_status_code status, const char *error_details)
+
+ ctypedef struct grpc_metadata_credentials_plugin:
+ void (*get_metadata)(
+ void *state, grpc_auth_metadata_context context,
+ grpc_credentials_plugin_metadata_cb cb, void *user_data)
+ void (*destroy)(void *state)
+ void *state
+ const char *type
+
+ grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
+ grpc_metadata_credentials_plugin plugin, void *reserved)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd
index 9ee487882aa..4c844e4cb6c 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pxd
@@ -66,6 +66,7 @@ cdef class Event:
cdef readonly call.Call operation_call
# For Server.request_call
+ cdef readonly bint is_new_request
cdef readonly CallDetails request_call_details
cdef readonly Metadata request_metadata
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx
index 8edee09c2d4..79a7f8f563b 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx
@@ -32,6 +32,30 @@ from grpc._cython._cygrpc cimport call
from grpc._cython._cygrpc cimport server
+class ConnectivityState:
+ idle = grpc.GRPC_CHANNEL_IDLE
+ connecting = grpc.GRPC_CHANNEL_CONNECTING
+ ready = grpc.GRPC_CHANNEL_READY
+ transient_failure = grpc.GRPC_CHANNEL_TRANSIENT_FAILURE
+ fatal_failure = grpc.GRPC_CHANNEL_FATAL_FAILURE
+
+
+class ChannelArgKey:
+ enable_census = grpc.GRPC_ARG_ENABLE_CENSUS
+ max_concurrent_streams = grpc.GRPC_ARG_MAX_CONCURRENT_STREAMS
+ max_message_length = grpc.GRPC_ARG_MAX_MESSAGE_LENGTH
+ http2_initial_sequence_number = grpc.GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER
+ default_authority = grpc.GRPC_ARG_DEFAULT_AUTHORITY
+ primary_user_agent_string = grpc.GRPC_ARG_PRIMARY_USER_AGENT_STRING
+ secondary_user_agent_string = grpc.GRPC_ARG_SECONDARY_USER_AGENT_STRING
+ ssl_target_name_override = grpc.GRPC_SSL_TARGET_NAME_OVERRIDE_ARG
+
+
+class WriteFlag:
+ buffer_hint = grpc.GRPC_WRITE_BUFFER_HINT
+ no_compress = grpc.GRPC_WRITE_NO_COMPRESS
+
+
class StatusCode:
ok = grpc.GRPC_STATUS_OK
cancelled = grpc.GRPC_STATUS_CANCELLED
@@ -88,7 +112,10 @@ cdef class Timespec:
def __cinit__(self, time):
if time is None:
self.c_time = grpc.gpr_now(grpc.GPR_CLOCK_REALTIME)
- elif isinstance(time, float):
+ return
+ if isinstance(time, int):
+ time = float(time)
+ if isinstance(time, float):
if time == float("+inf"):
self.c_time = grpc.gpr_inf_future(grpc.GPR_CLOCK_REALTIME)
elif time == float("-inf"):
@@ -97,8 +124,11 @@ cdef class Timespec:
self.c_time.seconds = time
self.c_time.nanoseconds = (time - float(self.c_time.seconds)) * 1e9
self.c_time.clock_type = grpc.GPR_CLOCK_REALTIME
+ elif isinstance(time, Timespec):
+ self.c_time = (time).c_time
else:
- raise TypeError("expected time to be float")
+ raise TypeError("expected time to be float, int, or Timespec, not {}"
+ .format(type(time)))
@property
def seconds(self):
@@ -166,6 +196,7 @@ cdef class Event:
object tag, call.Call operation_call,
CallDetails request_call_details,
Metadata request_metadata,
+ bint is_new_request,
Operations batch_operations):
self.type = type
self.success = success
@@ -174,6 +205,7 @@ cdef class Event:
self.request_call_details = request_call_details
self.request_metadata = request_metadata
self.batch_operations = batch_operations
+ self.is_new_request = is_new_request
cdef class ByteBuffer:
@@ -186,8 +218,14 @@ cdef class ByteBuffer:
pass
elif isinstance(data, basestring):
data = data.encode()
+ elif isinstance(data, ByteBuffer):
+ data = (data).bytes()
+ if data is None:
+ self.c_byte_buffer = NULL
+ return
else:
- raise TypeError("expected value to be of type str or bytes")
+ raise TypeError("expected value to be of type str, bytes, or "
+ "ByteBuffer, not {}".format(type(data)))
cdef char *c_data = data
data_slice = grpc.gpr_slice_from_copied_buffer(c_data, len(data))
@@ -409,12 +447,22 @@ cdef class Operation:
def type(self):
return self.c_op.type
+ @property
+ def has_status(self):
+ return self.c_op.type == grpc.GRPC_OP_RECV_STATUS_ON_CLIENT
+
@property
def received_message(self):
if self.c_op.type != grpc.GRPC_OP_RECV_MESSAGE:
raise TypeError("self must be an operation receiving a message")
return self._received_message
+ @property
+ def received_message_or_none(self):
+ if self.c_op.type != grpc.GRPC_OP_RECV_MESSAGE:
+ return None
+ return self._received_message
+
@property
def received_metadata(self):
if (self.c_op.type != grpc.GRPC_OP_RECV_INITIAL_METADATA and
@@ -422,12 +470,25 @@ cdef class Operation:
raise TypeError("self must be an operation receiving metadata")
return self._received_metadata
+ @property
+ def received_metadata_or_none(self):
+ if (self.c_op.type != grpc.GRPC_OP_RECV_INITIAL_METADATA and
+ self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT):
+ return None
+ return self._received_metadata
+
@property
def received_status_code(self):
if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT:
raise TypeError("self must be an operation receiving a status code")
return self._received_status_code
+ @property
+ def received_status_code_or_none(self):
+ if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT:
+ return None
+ return self._received_status_code
+
@property
def received_status_details(self):
if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT:
@@ -437,6 +498,15 @@ cdef class Operation:
else:
return None
+ @property
+ def received_status_details_or_none(self):
+ if self.c_op.type != grpc.GRPC_OP_RECV_STATUS_ON_CLIENT:
+ return None
+ if self._received_status_details:
+ return self._received_status_details
+ else:
+ return None
+
@property
def received_cancelled(self):
if self.c_op.type != grpc.GRPC_OP_RECV_CLOSE_ON_SERVER:
@@ -444,6 +514,12 @@ cdef class Operation:
"information")
return False if self._received_cancelled == 0 else True
+ @property
+ def received_cancelled_or_none(self):
+ if self.c_op.type != grpc.GRPC_OP_RECV_CLOSE_ON_SERVER:
+ return None
+ return False if self._received_cancelled == 0 else True
+
def __dealloc__(self):
# We *almost* don't need to do anything; most of the objects are handled by
# Python. The remaining one(s) are primitive fields filled in by GRPC core.
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx
index 6d20d2910c7..46df8bf77f8 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx
@@ -132,7 +132,7 @@ cdef class Server:
def cancel_all_calls(self):
if not self.is_shutting_down:
- raise ValueError("the server must be shutting down to cancel all calls")
+ raise RuntimeError("the server must be shutting down to cancel all calls")
elif self.is_shutdown:
return
else:
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index b20dda8a958..16ec12dac0d 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -44,6 +44,9 @@ from grpc._cython._cygrpc import completion_queue
from grpc._cython._cygrpc import records
from grpc._cython._cygrpc import server
+ConnectivityState = records.ConnectivityState
+ChannelArgKey = records.ChannelArgKey
+WriteFlag = records.WriteFlag
StatusCode = records.StatusCode
CallError = records.CallError
CompletionType = records.CompletionType
@@ -73,6 +76,8 @@ Operations = records.Operations
CallCredentials = credentials.CallCredentials
ChannelCredentials = credentials.ChannelCredentials
ServerCredentials = credentials.ServerCredentials
+CredentialsMetadataPlugin = credentials.CredentialsMetadataPlugin
+AuthMetadataContext = credentials.AuthMetadataContext
channel_credentials_google_default = (
credentials.channel_credentials_google_default)
@@ -88,6 +93,7 @@ call_credentials_jwt_access = (
call_credentials_refresh_token = (
credentials.call_credentials_google_refresh_token)
call_credentials_google_iam = credentials.call_credentials_google_iam
+call_credentials_metadata_plugin = credentials.call_credentials_metadata_plugin
server_credentials_ssl = credentials.server_credentials_ssl
CompletionQueue = completion_queue.CompletionQueue
diff --git a/src/python/grpcio/grpc/_links/invocation.py b/src/python/grpcio/grpc/_links/invocation.py
index 67ef86a1769..5ca0a0ee606 100644
--- a/src/python/grpcio/grpc/_links/invocation.py
+++ b/src/python/grpcio/grpc/_links/invocation.py
@@ -182,15 +182,15 @@ class _Kernel(object):
def _on_finish_event(self, operation_id, event, rpc_state):
_no_longer_due(_FINISH, rpc_state, operation_id, self._rpc_states)
- if event.status.code is _intermediary_low.Code.OK:
+ if event.status.code == _intermediary_low.Code.OK:
termination = links.Ticket.Termination.COMPLETION
- elif event.status.code is _intermediary_low.Code.CANCELLED:
+ elif event.status.code == _intermediary_low.Code.CANCELLED:
termination = links.Ticket.Termination.CANCELLATION
- elif event.status.code is _intermediary_low.Code.DEADLINE_EXCEEDED:
+ elif event.status.code == _intermediary_low.Code.DEADLINE_EXCEEDED:
termination = links.Ticket.Termination.EXPIRATION
- elif event.status.code is _intermediary_low.Code.UNIMPLEMENTED:
+ elif event.status.code == _intermediary_low.Code.UNIMPLEMENTED:
termination = links.Ticket.Termination.REMOTE_FAILURE
- elif event.status.code is _intermediary_low.Code.UNKNOWN:
+ elif event.status.code == _intermediary_low.Code.UNKNOWN:
termination = links.Ticket.Termination.LOCAL_FAILURE
else:
termination = links.Ticket.Termination.TRANSMISSION_FAILURE
@@ -262,7 +262,7 @@ class _Kernel(object):
self._channel, self._completion_queue, '/%s/%s' % (group, method),
self._host, time.time() + timeout)
if options is not None and options.credentials is not None:
- call.set_credentials(options.credentials._intermediary_low_credentials)
+ call.set_credentials(options.credentials._low_credentials)
if transformed_initial_metadata is not None:
for metadata_key, metadata_value in transformed_initial_metadata:
call.add_metadata(metadata_key, metadata_value)
diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py
index f56df84007d..01edee68961 100644
--- a/src/python/grpcio/grpc/_links/service.py
+++ b/src/python/grpcio/grpc/_links/service.py
@@ -254,12 +254,12 @@ class _Kernel(object):
rpc_state = self._rpc_states[call]
_no_longer_due(_FINISH, rpc_state, call, self._rpc_states)
code = event.status.code
- if code is _intermediary_low.Code.OK:
+ if code == _intermediary_low.Code.OK:
return
- if code is _intermediary_low.Code.CANCELLED:
+ if code == _intermediary_low.Code.CANCELLED:
termination = links.Ticket.Termination.CANCELLATION
- elif code is _intermediary_low.Code.DEADLINE_EXCEEDED:
+ elif code == _intermediary_low.Code.DEADLINE_EXCEEDED:
termination = links.Ticket.Termination.EXPIRATION
else:
termination = links.Ticket.Termination.TRANSMISSION_FAILURE
diff --git a/src/python/grpcio/grpc/beta/_server.py b/src/python/grpcio/grpc/beta/_server.py
index 4f454437c00..2b520cc7e5f 100644
--- a/src/python/grpcio/grpc/beta/_server.py
+++ b/src/python/grpcio/grpc/beta/_server.py
@@ -170,7 +170,7 @@ class _Server(interfaces.Server):
with self._lock:
if self._end_link is None:
return self._grpc_link.add_port(
- address, server_credentials._intermediary_low_credentials) # pylint: disable=protected-access
+ address, server_credentials._low_credentials) # pylint: disable=protected-access
else:
raise ValueError('Can\'t add port to serving server!')
diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py
index c9d64ad35a0..a0ca330d2c0 100644
--- a/src/python/grpcio/grpc/beta/implementations.py
+++ b/src/python/grpcio/grpc/beta/implementations.py
@@ -36,6 +36,7 @@ import threading # pylint: disable=unused-import
# cardinality and face are referenced from specification in this module.
from grpc._adapter import _intermediary_low
+from grpc._adapter import _low
from grpc._adapter import _types
from grpc.beta import _connectivity_channel
from grpc.beta import _server
@@ -48,7 +49,7 @@ _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
'Exception calling channel subscription callback!')
-class ClientCredentials(object):
+class ChannelCredentials(object):
"""A value encapsulating the data required to create a secure Channel.
This class and its instances have no supported interface - it exists to define
@@ -56,13 +57,12 @@ class ClientCredentials(object):
functions.
"""
- def __init__(self, low_credentials, intermediary_low_credentials):
+ def __init__(self, low_credentials):
self._low_credentials = low_credentials
- self._intermediary_low_credentials = intermediary_low_credentials
-def ssl_client_credentials(root_certificates, private_key, certificate_chain):
- """Creates a ClientCredentials for use with an SSL-enabled Channel.
+def ssl_channel_credentials(root_certificates, private_key, certificate_chain):
+ """Creates a ChannelCredentials for use with an SSL-enabled Channel.
Args:
root_certificates: The PEM-encoded root certificates or None to ask for
@@ -73,12 +73,73 @@ def ssl_client_credentials(root_certificates, private_key, certificate_chain):
certificate chain should be used.
Returns:
- A ClientCredentials for use with an SSL-enabled Channel.
+ A ChannelCredentials for use with an SSL-enabled Channel.
"""
- intermediary_low_credentials = _intermediary_low.ClientCredentials(
- root_certificates, private_key, certificate_chain)
- return ClientCredentials(
- intermediary_low_credentials._internal, intermediary_low_credentials) # pylint: disable=protected-access
+ return ChannelCredentials(_low.channel_credentials_ssl(
+ root_certificates, private_key, certificate_chain))
+
+
+class CallCredentials(object):
+ """A value encapsulating data asserting an identity over an *established*
+ channel. May be composed with ChannelCredentials to always assert identity for
+ every call over that channel.
+
+ This class and its instances have no supported interface - it exists to define
+ the type of its instances and its instances exist to be passed to other
+ functions.
+ """
+
+ def __init__(self, low_credentials):
+ self._low_credentials = low_credentials
+
+
+def metadata_call_credentials(metadata_plugin, name=None):
+ """Construct CallCredentials from an interfaces.GRPCAuthMetadataPlugin.
+
+ Args:
+ metadata_plugin: An interfaces.GRPCAuthMetadataPlugin to use in constructing
+ the CallCredentials object.
+
+ Returns:
+ A CallCredentials object for use in a GRPCCallOptions object.
+ """
+ if name is None:
+ name = metadata_plugin.__name__
+ return CallCredentials(
+ _low.call_credentials_metadata_plugin(metadata_plugin, name))
+
+def composite_call_credentials(call_credentials, additional_call_credentials):
+ """Compose two CallCredentials to make a new one.
+
+ Args:
+ call_credentials: A CallCredentials object.
+ additional_call_credentials: Another CallCredentials object to compose on
+ top of call_credentials.
+
+ Returns:
+ A CallCredentials object for use in a GRPCCallOptions object.
+ """
+ return CallCredentials(
+ _low.call_credentials_composite(
+ call_credentials._low_credentials,
+ additional_call_credentials._low_credentials))
+
+def composite_channel_credentials(channel_credentials,
+ additional_call_credentials):
+ """Compose ChannelCredentials on top of client credentials to make a new one.
+
+ Args:
+ channel_credentials: A ChannelCredentials object.
+ additional_call_credentials: A CallCredentials object to compose on
+ top of channel_credentials.
+
+ Returns:
+ A ChannelCredentials object for use in a GRPCCallOptions object.
+ """
+ return ChannelCredentials(
+ _low.channel_credentials_composite(
+ channel_credentials._low_credentials,
+ additional_call_credentials._low_credentials))
class Channel(object):
@@ -135,19 +196,19 @@ def insecure_channel(host, port):
return Channel(intermediary_low_channel._internal, intermediary_low_channel) # pylint: disable=protected-access
-def secure_channel(host, port, client_credentials):
+def secure_channel(host, port, channel_credentials):
"""Creates a secure Channel to a remote host.
Args:
host: The name of the remote host to which to connect.
port: The port of the remote host to which to connect.
- client_credentials: A ClientCredentials.
+ channel_credentials: A ChannelCredentials.
Returns:
A secure Channel to the remote host through which RPCs may be conducted.
"""
intermediary_low_channel = _intermediary_low.Channel(
- '%s:%d' % (host, port), client_credentials._intermediary_low_credentials)
+ '%s:%d' % (host, port), channel_credentials._low_credentials)
return Channel(intermediary_low_channel._internal, intermediary_low_channel) # pylint: disable=protected-access
@@ -251,9 +312,8 @@ class ServerCredentials(object):
functions.
"""
- def __init__(self, low_credentials, intermediary_low_credentials):
+ def __init__(self, low_credentials):
self._low_credentials = low_credentials
- self._intermediary_low_credentials = intermediary_low_credentials
def ssl_server_credentials(
@@ -282,11 +342,9 @@ def ssl_server_credentials(
raise ValueError(
'Illegal to require client auth without providing root certificates!')
else:
- intermediary_low_credentials = _intermediary_low.ServerCredentials(
+ return ServerCredentials(_low.server_credentials_ssl(
root_certificates, private_key_certificate_chain_pairs,
- require_client_auth)
- return ServerCredentials(
- intermediary_low_credentials._internal, intermediary_low_credentials) # pylint: disable=protected-access
+ require_client_auth))
class ServerOptions(object):
diff --git a/src/python/grpcio/grpc/beta/interfaces.py b/src/python/grpcio/grpc/beta/interfaces.py
index d4ca56500ff..0663119163f 100644
--- a/src/python/grpcio/grpc/beta/interfaces.py
+++ b/src/python/grpcio/grpc/beta/interfaces.py
@@ -100,14 +100,55 @@ def grpc_call_options(disable_compression=False, credentials=None):
disable_compression: A boolean indicating whether or not compression should
be disabled for the request object of the RPC. Only valid for
request-unary RPCs.
- credentials: Reserved for gRPC per-call credentials. The type for this does
- not exist yet at the Python level.
+ credentials: A CallCredentials object to use for the invoked RPC.
"""
- if credentials is not None:
- raise ValueError('`credentials` is a reserved argument')
return GRPCCallOptions(disable_compression, None, credentials)
+class GRPCAuthMetadataContext(object):
+ """Provides information to call credentials metadata plugins.
+
+ Attributes:
+ service_url: A string URL of the service being called into.
+ method_name: A string of the fully qualified method name being called.
+ """
+ __metaclass__ = abc.ABCMeta
+
+
+class GRPCAuthMetadataPluginCallback(object):
+ """Callback object received by a metadata plugin."""
+ __metaclass__ = abc.ABCMeta
+
+ def __call__(self, metadata, error):
+ """Inform the gRPC runtime of the metadata to construct a CallCredentials.
+
+ Args:
+ metadata: An iterable of 2-sequences (e.g. tuples) of metadata key/value
+ pairs.
+ error: An Exception to indicate error or None to indicate success.
+ """
+ raise NotImplementedError()
+
+
+class GRPCAuthMetadataPlugin(object):
+ """
+ """
+ __metaclass__ = abc.ABCMeta
+
+ def __call__(self, context, callback):
+ """Invoke the plugin.
+
+ Must not block. Need only be called by the gRPC runtime.
+
+ Args:
+ context: A GRPCAuthMetadataContext providing information on what the
+ plugin is being used for.
+ callback: A GRPCAuthMetadataPluginCallback to be invoked either
+ synchronously or asynchronously.
+ """
+ raise NotImplementedError()
+
+
class GRPCServicerContext(object):
"""Exposes gRPC-specific options and behaviors to code servicing RPCs."""
__metaclass__ = abc.ABCMeta
diff --git a/src/python/grpcio/setup.py b/src/python/grpcio/setup.py
index 8ac185bd6bf..a948ca1fac6 100644
--- a/src/python/grpcio/setup.py
+++ b/src/python/grpcio/setup.py
@@ -57,19 +57,6 @@ ENABLE_CYTHON_TRACING = os.environ.get(
# the installation.
INSTALL_TESTS = os.environ.get('GRPC_PYTHON_INSTALL_TESTS', False)
-C_EXTENSION_SOURCES = (
- 'grpc/_adapter/_c/module.c',
- 'grpc/_adapter/_c/types.c',
- 'grpc/_adapter/_c/utility.c',
- 'grpc/_adapter/_c/types/call_credentials.c',
- 'grpc/_adapter/_c/types/channel_credentials.c',
- 'grpc/_adapter/_c/types/server_credentials.c',
- 'grpc/_adapter/_c/types/completion_queue.c',
- 'grpc/_adapter/_c/types/call.c',
- 'grpc/_adapter/_c/types/channel.c',
- 'grpc/_adapter/_c/types/server.c',
-)
-
CYTHON_EXTENSION_PACKAGE_NAMES = ()
CYTHON_EXTENSION_MODULE_NAMES = (
@@ -94,14 +81,6 @@ if not "darwin" in sys.platform:
EXTENSION_LIBRARIES += ('rt',)
-C_EXTENSION_MODULE = _core.Extension(
- 'grpc._adapter._c', sources=list(C_EXTENSION_SOURCES),
- include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES),
- libraries=list(EXTENSION_LIBRARIES)
-)
-EXTENSION_MODULES = [C_EXTENSION_MODULE]
-
-
def cython_extensions(package_names, module_names, include_dirs, libraries,
build_with_cython=False):
file_extension = 'pyx' if build_with_cython else 'c'
@@ -185,7 +164,7 @@ else:
setuptools.setup(
name='grpcio',
version='0.11.0b2',
- ext_modules=EXTENSION_MODULES + CYTHON_EXTENSION_MODULES,
+ ext_modules=CYTHON_EXTENSION_MODULES,
packages=list(PACKAGES),
package_dir=PACKAGE_DIRECTORIES,
install_requires=INSTALL_REQUIRES,
diff --git a/src/python/grpcio/tests/interop/_secure_interop_test.py b/src/python/grpcio/tests/interop/_secure_interop_test.py
index a0fef1fc203..7e3061133f1 100644
--- a/src/python/grpcio/tests/interop/_secure_interop_test.py
+++ b/src/python/grpcio/tests/interop/_secure_interop_test.py
@@ -55,7 +55,7 @@ class SecureInteropTest(
self.server.start()
self.stub = test_pb2.beta_create_TestService_stub(
test_utilities.not_really_secure_channel(
- '[::]', port, implementations.ssl_client_credentials(
+ '[::]', port, implementations.ssl_channel_credentials(
resources.test_root_certificates(), None, None),
_SERVER_HOST_OVERRIDE))
diff --git a/src/python/grpcio/tests/interop/client.py b/src/python/grpcio/tests/interop/client.py
index 9449ff5429f..5c00bce0149 100644
--- a/src/python/grpcio/tests/interop/client.py
+++ b/src/python/grpcio/tests/interop/client.py
@@ -94,7 +94,7 @@ def _stub(args):
channel = test_utilities.not_really_secure_channel(
args.server_host, args.server_port,
- implementations.ssl_client_credentials(root_certificates, None, None),
+ implementations.ssl_channel_credentials(root_certificates, None, None),
args.server_host_override)
stub = test_pb2.beta_create_TestService_stub(
channel, metadata_transformer=metadata_transformer)
diff --git a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
index 90ad0b9bcb5..a6fd82388c0 100644
--- a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
+++ b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
@@ -115,6 +115,7 @@ class EchoTest(unittest.TestCase):
def tearDown(self):
self.server.stop()
+ self.server.cancel_all_calls()
self.server_completion_queue.stop()
self.client_completion_queue.stop()
self.server_completion_queue_thread.join()
@@ -286,11 +287,6 @@ class EchoTest(unittest.TestCase):
set((server_trailing_metadata_key,
server_trailing_binary_metadata_key,)))
- server_timeout_none_event = self.server_completion_queue.get(0)
- self.assertIsNone(server_timeout_none_event)
- client_timeout_none_event = self.client_completion_queue.get(0)
- self.assertIsNone(client_timeout_none_event)
-
self.assertSequenceEqual(test_data, server_data)
self.assertSequenceEqual(test_data, client_data)
@@ -335,6 +331,7 @@ class CancellationTest(unittest.TestCase):
def tearDown(self):
self.server.stop()
+ self.server.cancel_all_calls()
self.server_completion_queue.stop()
self.client_completion_queue.stop()
self.server_completion_queue_thread.join()
@@ -410,14 +407,9 @@ class CancellationTest(unittest.TestCase):
finish_event = self.client_events.get()
self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind)
- self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'),
+ self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'),
finish_event.status)
- server_timeout_none_event = self.server_completion_queue.get(0)
- self.assertIsNone(server_timeout_none_event)
- client_timeout_none_event = self.client_completion_queue.get(0)
- self.assertIsNone(client_timeout_none_event)
-
self.assertSequenceEqual(test_data, server_data)
self.assertSequenceEqual(test_data, client_data)
diff --git a/src/python/grpcio/tests/unit/_adapter/_low_test.py b/src/python/grpcio/tests/unit/_adapter/_low_test.py
index 39b6f247b4e..ec46617996b 100644
--- a/src/python/grpcio/tests/unit/_adapter/_low_test.py
+++ b/src/python/grpcio/tests/unit/_adapter/_low_test.py
@@ -80,11 +80,11 @@ class InsecureServerInsecureClient(unittest.TestCase):
del self.client_channel
self.client_completion_queue.shutdown()
- while (self.client_completion_queue.next().type !=
+ while (self.client_completion_queue.next(float('+inf')).type !=
_types.EventType.QUEUE_SHUTDOWN):
pass
self.server_completion_queue.shutdown()
- while (self.server_completion_queue.next().type !=
+ while (self.server_completion_queue.next(float('+inf')).type !=
_types.EventType.QUEUE_SHUTDOWN):
pass
@@ -294,8 +294,12 @@ class HangingServerShutdown(unittest.TestCase):
# Now try to shutdown the server and expect that we see server shutdown
# almost immediately after calling cancel_all_calls.
+
+ # First attempt to cancel all calls before shutting down, and expect
+ # our state machine to catch the erroneous API use.
with self.assertRaises(RuntimeError):
self.server.cancel_all_calls()
+
shutdown_tag = object()
self.server.shutdown(shutdown_tag)
pre_cancel_timestamp = time.time()
diff --git a/src/python/grpcio/tests/unit/_cython/adapter_low_test.py b/src/python/grpcio/tests/unit/_cython/adapter_low_test.py
deleted file mode 100644
index f1bec238cf5..00000000000
--- a/src/python/grpcio/tests/unit/_cython/adapter_low_test.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Fork of grpc._adapter._low_test; the grpc._cython.types adapter in
-# grpc._cython.low should transparently support the semantics expected of
-# grpc._adapter._low.
-
-import time
-import unittest
-
-from grpc._adapter import _types
-from grpc._cython import adapter_low as _low
-
-
-class InsecureServerInsecureClient(unittest.TestCase):
-
- def setUp(self):
- self.server_completion_queue = _low.CompletionQueue()
- self.server = _low.Server(self.server_completion_queue, [])
- self.port = self.server.add_http2_port('[::]:0')
- self.client_completion_queue = _low.CompletionQueue()
- self.client_channel = _low.Channel('localhost:%d'%self.port, [])
-
- self.server.start()
-
- def tearDown(self):
- self.server.shutdown()
- del self.client_channel
-
- self.client_completion_queue.shutdown()
- while (self.client_completion_queue.next().type !=
- _types.EventType.QUEUE_SHUTDOWN):
- pass
- self.server_completion_queue.shutdown()
- while (self.server_completion_queue.next().type !=
- _types.EventType.QUEUE_SHUTDOWN):
- pass
-
- del self.client_completion_queue
- del self.server_completion_queue
- del self.server
-
- @unittest.skip('TODO(atash): implement grpc._cython.adapter_low')
- def testEcho(self):
- DEADLINE = time.time()+5
- DEADLINE_TOLERANCE = 0.25
- CLIENT_METADATA_ASCII_KEY = 'key'
- CLIENT_METADATA_ASCII_VALUE = 'val'
- CLIENT_METADATA_BIN_KEY = 'key-bin'
- CLIENT_METADATA_BIN_VALUE = b'\0'*1000
- SERVER_INITIAL_METADATA_KEY = 'init_me_me_me'
- SERVER_INITIAL_METADATA_VALUE = 'whodawha?'
- SERVER_TRAILING_METADATA_KEY = 'california_is_in_a_drought'
- SERVER_TRAILING_METADATA_VALUE = 'zomg it is'
- SERVER_STATUS_CODE = _types.StatusCode.OK
- SERVER_STATUS_DETAILS = 'our work is never over'
- REQUEST = 'in death a member of project mayhem has a name'
- RESPONSE = 'his name is robert paulson'
- METHOD = 'twinkies'
- HOST = 'hostess'
- server_request_tag = object()
- request_call_result = self.server.request_call(self.server_completion_queue,
- server_request_tag)
-
- self.assertEqual(_types.CallError.OK, request_call_result)
-
- client_call_tag = object()
- client_call = self.client_channel.create_call(self.client_completion_queue,
- METHOD, HOST, DEADLINE)
- client_initial_metadata = [
- (CLIENT_METADATA_ASCII_KEY, CLIENT_METADATA_ASCII_VALUE),
- (CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)]
- client_start_batch_result = client_call.start_batch([
- _types.OpArgs.send_initial_metadata(client_initial_metadata),
- _types.OpArgs.send_message(REQUEST),
- _types.OpArgs.send_close_from_client(),
- _types.OpArgs.recv_initial_metadata(),
- _types.OpArgs.recv_message(),
- _types.OpArgs.recv_status_on_client()
- ], client_call_tag)
- self.assertEqual(_types.CallError.OK, client_start_batch_result)
-
- request_event = self.server_completion_queue.next(DEADLINE)
- self.assertEqual(_types.EventType.OP_COMPLETE, request_event.type)
- self.assertIsInstance(request_event.call, _low.Call)
- self.assertIs(server_request_tag, request_event.tag)
- self.assertEqual(1, len(request_event.results))
- self.assertEqual(dict(client_initial_metadata),
- dict(request_event.results[0].initial_metadata))
- self.assertEqual(METHOD, request_event.call_details.method)
- self.assertEqual(HOST, request_event.call_details.host)
- self.assertLess(abs(DEADLINE - request_event.call_details.deadline),
- DEADLINE_TOLERANCE)
-
- server_call_tag = object()
- server_call = request_event.call
- server_initial_metadata = [
- (SERVER_INITIAL_METADATA_KEY, SERVER_INITIAL_METADATA_VALUE)]
- server_trailing_metadata = [
- (SERVER_TRAILING_METADATA_KEY, SERVER_TRAILING_METADATA_VALUE)]
- server_start_batch_result = server_call.start_batch([
- _types.OpArgs.send_initial_metadata(server_initial_metadata),
- _types.OpArgs.recv_message(),
- _types.OpArgs.send_message(RESPONSE),
- _types.OpArgs.recv_close_on_server(),
- _types.OpArgs.send_status_from_server(
- server_trailing_metadata, SERVER_STATUS_CODE, SERVER_STATUS_DETAILS)
- ], server_call_tag)
- self.assertEqual(_types.CallError.OK, server_start_batch_result)
-
- client_event = self.client_completion_queue.next(DEADLINE)
- server_event = self.server_completion_queue.next(DEADLINE)
-
- self.assertEqual(6, len(client_event.results))
- found_client_op_types = set()
- for client_result in client_event.results:
- # we expect each op type to be unique
- self.assertNotIn(client_result.type, found_client_op_types)
- found_client_op_types.add(client_result.type)
- if client_result.type == _types.OpType.RECV_INITIAL_METADATA:
- self.assertEqual(dict(server_initial_metadata),
- dict(client_result.initial_metadata))
- elif client_result.type == _types.OpType.RECV_MESSAGE:
- self.assertEqual(RESPONSE, client_result.message)
- elif client_result.type == _types.OpType.RECV_STATUS_ON_CLIENT:
- self.assertEqual(dict(server_trailing_metadata),
- dict(client_result.trailing_metadata))
- self.assertEqual(SERVER_STATUS_DETAILS, client_result.status.details)
- self.assertEqual(SERVER_STATUS_CODE, client_result.status.code)
- self.assertEqual(set([
- _types.OpType.SEND_INITIAL_METADATA,
- _types.OpType.SEND_MESSAGE,
- _types.OpType.SEND_CLOSE_FROM_CLIENT,
- _types.OpType.RECV_INITIAL_METADATA,
- _types.OpType.RECV_MESSAGE,
- _types.OpType.RECV_STATUS_ON_CLIENT
- ]), found_client_op_types)
-
- self.assertEqual(5, len(server_event.results))
- found_server_op_types = set()
- for server_result in server_event.results:
- self.assertNotIn(client_result.type, found_server_op_types)
- found_server_op_types.add(server_result.type)
- if server_result.type == _types.OpType.RECV_MESSAGE:
- self.assertEqual(REQUEST, server_result.message)
- elif server_result.type == _types.OpType.RECV_CLOSE_ON_SERVER:
- self.assertFalse(server_result.cancelled)
- self.assertEqual(set([
- _types.OpType.SEND_INITIAL_METADATA,
- _types.OpType.RECV_MESSAGE,
- _types.OpType.SEND_MESSAGE,
- _types.OpType.RECV_CLOSE_ON_SERVER,
- _types.OpType.SEND_STATUS_FROM_SERVER
- ]), found_server_op_types)
-
- del client_call
- del server_call
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
index 84ee5c9eb5f..876da88de95 100644
--- a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
@@ -28,11 +28,24 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import time
+import threading
import unittest
from grpc._cython import cygrpc
from tests.unit._cython import test_utilities
from tests.unit import test_common
+from tests.unit import resources
+
+
+_SSL_HOST_OVERRIDE = 'foo.test.google.fr'
+_CALL_CREDENTIALS_METADATA_KEY = 'call-creds-key'
+_CALL_CREDENTIALS_METADATA_VALUE = 'call-creds-value'
+
+def _metadata_plugin_callback(context, callback):
+ callback(cygrpc.Metadata(
+ [cygrpc.Metadatum(_CALL_CREDENTIALS_METADATA_KEY,
+ _CALL_CREDENTIALS_METADATA_VALUE)]),
+ cygrpc.StatusCode.ok, '')
class TypeSmokeTest(unittest.TestCase):
@@ -89,7 +102,17 @@ class TypeSmokeTest(unittest.TestCase):
channel = cygrpc.Channel('[::]:0', cygrpc.ChannelArgs([]))
del channel
- @unittest.skip('TODO(atash): undo skip after #2229 is merged')
+ def testCredentialsMetadataPluginUpDown(self):
+ plugin = cygrpc.CredentialsMetadataPlugin(
+ lambda ignored_a, ignored_b: None, '')
+ del plugin
+
+ def testCallCredentialsFromPluginUpDown(self):
+ plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, '')
+ call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
+ del plugin
+ del call_credentials
+
def testServerStartNoExplicitShutdown(self):
server = cygrpc.Server()
completion_queue = cygrpc.CompletionQueue()
@@ -99,7 +122,6 @@ class TypeSmokeTest(unittest.TestCase):
server.start()
del server
- @unittest.skip('TODO(atash): undo skip after #2229 is merged')
def testServerStartShutdown(self):
completion_queue = cygrpc.CompletionQueue()
server = cygrpc.Server()
@@ -262,5 +284,169 @@ class InsecureServerInsecureClient(unittest.TestCase):
del server_call
+class SecureServerSecureClient(unittest.TestCase):
+
+ def setUp(self):
+ server_credentials = cygrpc.server_credentials_ssl(
+ None, [cygrpc.SslPemKeyCertPair(resources.private_key(),
+ resources.certificate_chain())], False)
+ channel_credentials = cygrpc.channel_credentials_ssl(
+ resources.test_root_certificates(), None)
+ self.server_completion_queue = cygrpc.CompletionQueue()
+ self.server = cygrpc.Server()
+ self.server.register_completion_queue(self.server_completion_queue)
+ self.port = self.server.add_http2_port('[::]:0', server_credentials)
+ self.server.start()
+ self.client_completion_queue = cygrpc.CompletionQueue()
+ client_channel_arguments = cygrpc.ChannelArgs([
+ cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
+ _SSL_HOST_OVERRIDE)])
+ self.client_channel = cygrpc.Channel(
+ 'localhost:{}'.format(self.port), client_channel_arguments,
+ channel_credentials)
+
+ def tearDown(self):
+ del self.server
+ del self.client_completion_queue
+ del self.server_completion_queue
+
+ def testEcho(self):
+ DEADLINE = time.time()+5
+ DEADLINE_TOLERANCE = 0.25
+ CLIENT_METADATA_ASCII_KEY = b'key'
+ CLIENT_METADATA_ASCII_VALUE = b'val'
+ CLIENT_METADATA_BIN_KEY = b'key-bin'
+ CLIENT_METADATA_BIN_VALUE = b'\0'*1000
+ SERVER_INITIAL_METADATA_KEY = b'init_me_me_me'
+ SERVER_INITIAL_METADATA_VALUE = b'whodawha?'
+ SERVER_TRAILING_METADATA_KEY = b'california_is_in_a_drought'
+ SERVER_TRAILING_METADATA_VALUE = b'zomg it is'
+ SERVER_STATUS_CODE = cygrpc.StatusCode.ok
+ SERVER_STATUS_DETAILS = b'our work is never over'
+ REQUEST = b'in death a member of project mayhem has a name'
+ RESPONSE = b'his name is robert paulson'
+ METHOD = b'/twinkies'
+ HOST = None # Default host
+
+ cygrpc_deadline = cygrpc.Timespec(DEADLINE)
+
+ server_request_tag = object()
+ request_call_result = self.server.request_call(
+ self.server_completion_queue, self.server_completion_queue,
+ server_request_tag)
+
+ self.assertEqual(cygrpc.CallError.ok, request_call_result)
+
+ plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, '')
+ call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
+
+ client_call_tag = object()
+ client_call = self.client_channel.create_call(
+ None, 0, self.client_completion_queue, METHOD, HOST, cygrpc_deadline)
+ client_call.set_credentials(call_credentials)
+ client_initial_metadata = cygrpc.Metadata([
+ cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
+ CLIENT_METADATA_ASCII_VALUE),
+ cygrpc.Metadatum(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)])
+ client_start_batch_result = client_call.start_batch(cygrpc.Operations([
+ cygrpc.operation_send_initial_metadata(client_initial_metadata),
+ cygrpc.operation_send_message(REQUEST),
+ cygrpc.operation_send_close_from_client(),
+ cygrpc.operation_receive_initial_metadata(),
+ cygrpc.operation_receive_message(),
+ cygrpc.operation_receive_status_on_client()
+ ]), client_call_tag)
+ self.assertEqual(cygrpc.CallError.ok, client_start_batch_result)
+ client_event_future = test_utilities.CompletionQueuePollFuture(
+ self.client_completion_queue, cygrpc_deadline)
+
+ request_event = self.server_completion_queue.poll(cygrpc_deadline)
+ self.assertEqual(cygrpc.CompletionType.operation_complete,
+ request_event.type)
+ self.assertIsInstance(request_event.operation_call, cygrpc.Call)
+ self.assertIs(server_request_tag, request_event.tag)
+ self.assertEqual(0, len(request_event.batch_operations))
+ client_metadata_with_credentials = list(client_initial_metadata) + [
+ (_CALL_CREDENTIALS_METADATA_KEY, _CALL_CREDENTIALS_METADATA_VALUE)]
+ self.assertTrue(
+ test_common.metadata_transmitted(client_metadata_with_credentials,
+ request_event.request_metadata))
+ self.assertEqual(METHOD, request_event.request_call_details.method)
+ self.assertEqual(_SSL_HOST_OVERRIDE,
+ request_event.request_call_details.host)
+ self.assertLess(
+ abs(DEADLINE - float(request_event.request_call_details.deadline)),
+ DEADLINE_TOLERANCE)
+
+ server_call_tag = object()
+ server_call = request_event.operation_call
+ server_initial_metadata = cygrpc.Metadata([
+ cygrpc.Metadatum(SERVER_INITIAL_METADATA_KEY,
+ SERVER_INITIAL_METADATA_VALUE)])
+ server_trailing_metadata = cygrpc.Metadata([
+ cygrpc.Metadatum(SERVER_TRAILING_METADATA_KEY,
+ SERVER_TRAILING_METADATA_VALUE)])
+ server_start_batch_result = server_call.start_batch([
+ cygrpc.operation_send_initial_metadata(server_initial_metadata),
+ cygrpc.operation_receive_message(),
+ cygrpc.operation_send_message(RESPONSE),
+ cygrpc.operation_receive_close_on_server(),
+ cygrpc.operation_send_status_from_server(
+ server_trailing_metadata, SERVER_STATUS_CODE, SERVER_STATUS_DETAILS)
+ ], server_call_tag)
+ self.assertEqual(cygrpc.CallError.ok, server_start_batch_result)
+
+ client_event = client_event_future.result()
+ server_event = self.server_completion_queue.poll(cygrpc_deadline)
+
+ self.assertEqual(6, len(client_event.batch_operations))
+ found_client_op_types = set()
+ for client_result in client_event.batch_operations:
+ # we expect each op type to be unique
+ self.assertNotIn(client_result.type, found_client_op_types)
+ found_client_op_types.add(client_result.type)
+ if client_result.type == cygrpc.OperationType.receive_initial_metadata:
+ self.assertTrue(
+ test_common.metadata_transmitted(server_initial_metadata,
+ client_result.received_metadata))
+ elif client_result.type == cygrpc.OperationType.receive_message:
+ self.assertEqual(RESPONSE, client_result.received_message.bytes())
+ elif client_result.type == cygrpc.OperationType.receive_status_on_client:
+ self.assertTrue(
+ test_common.metadata_transmitted(server_trailing_metadata,
+ client_result.received_metadata))
+ self.assertEqual(SERVER_STATUS_DETAILS,
+ client_result.received_status_details)
+ self.assertEqual(SERVER_STATUS_CODE, client_result.received_status_code)
+ self.assertEqual(set([
+ cygrpc.OperationType.send_initial_metadata,
+ cygrpc.OperationType.send_message,
+ cygrpc.OperationType.send_close_from_client,
+ cygrpc.OperationType.receive_initial_metadata,
+ cygrpc.OperationType.receive_message,
+ cygrpc.OperationType.receive_status_on_client
+ ]), found_client_op_types)
+
+ self.assertEqual(5, len(server_event.batch_operations))
+ found_server_op_types = set()
+ for server_result in server_event.batch_operations:
+ self.assertNotIn(client_result.type, found_server_op_types)
+ found_server_op_types.add(server_result.type)
+ if server_result.type == cygrpc.OperationType.receive_message:
+ self.assertEqual(REQUEST, server_result.received_message.bytes())
+ elif server_result.type == cygrpc.OperationType.receive_close_on_server:
+ self.assertFalse(server_result.received_cancelled)
+ self.assertEqual(set([
+ cygrpc.OperationType.send_initial_metadata,
+ cygrpc.OperationType.receive_message,
+ cygrpc.OperationType.send_message,
+ cygrpc.OperationType.receive_close_on_server,
+ cygrpc.OperationType.send_status_from_server
+ ]), found_server_op_types)
+
+ del client_call
+ del server_call
+
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/beta/_beta_features_test.py b/src/python/grpcio/tests/unit/beta/_beta_features_test.py
index 5a7492ee9ea..ea44177b499 100644
--- a/src/python/grpcio/tests/unit/beta/_beta_features_test.py
+++ b/src/python/grpcio/tests/unit/beta/_beta_features_test.py
@@ -42,6 +42,9 @@ from tests.unit.framework.common import test_constants
_SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
+_PER_RPC_CREDENTIALS_METADATA_KEY = 'my-call-credentials-metadata-key'
+_PER_RPC_CREDENTIALS_METADATA_VALUE = 'my-call-credentials-metadata-value'
+
_GROUP = 'group'
_UNARY_UNARY = 'unary-unary'
_UNARY_STREAM = 'unary-stream'
@@ -63,6 +66,7 @@ class _Servicer(object):
with self._condition:
self._request = request
self._peer = context.protocol_context().peer()
+ self._invocation_metadata = context.invocation_metadata()
context.protocol_context().disable_next_response_compression()
self._serviced = True
self._condition.notify_all()
@@ -72,6 +76,7 @@ class _Servicer(object):
with self._condition:
self._request = request
self._peer = context.protocol_context().peer()
+ self._invocation_metadata = context.invocation_metadata()
context.protocol_context().disable_next_response_compression()
self._serviced = True
self._condition.notify_all()
@@ -83,6 +88,7 @@ class _Servicer(object):
self._request = request
with self._condition:
self._peer = context.protocol_context().peer()
+ self._invocation_metadata = context.invocation_metadata()
context.protocol_context().disable_next_response_compression()
self._serviced = True
self._condition.notify_all()
@@ -95,6 +101,7 @@ class _Servicer(object):
context.protocol_context().disable_next_response_compression()
yield _RESPONSE
with self._condition:
+ self._invocation_metadata = context.invocation_metadata()
self._serviced = True
self._condition.notify_all()
@@ -137,6 +144,11 @@ class _BlockingIterator(object):
self._condition.notify_all()
+def _metadata_plugin(context, callback):
+ callback([(_PER_RPC_CREDENTIALS_METADATA_KEY,
+ _PER_RPC_CREDENTIALS_METADATA_VALUE)], None)
+
+
class BetaFeaturesTest(unittest.TestCase):
def setUp(self):
@@ -167,10 +179,12 @@ class BetaFeaturesTest(unittest.TestCase):
[(resources.private_key(), resources.certificate_chain(),),])
port = self._server.add_secure_port('[::]:0', server_credentials)
self._server.start()
- self._client_credentials = implementations.ssl_client_credentials(
+ self._channel_credentials = implementations.ssl_channel_credentials(
resources.test_root_certificates(), None, None)
+ self._call_credentials = implementations.metadata_call_credentials(
+ _metadata_plugin)
channel = test_utilities.not_really_secure_channel(
- 'localhost', port, self._client_credentials, _SERVER_HOST_OVERRIDE)
+ 'localhost', port, self._channel_credentials, _SERVER_HOST_OVERRIDE)
stub_options = implementations.stub_options(
thread_pool_size=test_constants.POOL_SIZE)
self._dynamic_stub = implementations.dynamic_stub(
@@ -181,21 +195,36 @@ class BetaFeaturesTest(unittest.TestCase):
self._server.stop(test_constants.SHORT_TIMEOUT).wait()
def test_unary_unary(self):
- call_options = interfaces.grpc_call_options(disable_compression=True)
+ call_options = interfaces.grpc_call_options(
+ disable_compression=True, credentials=self._call_credentials)
response = getattr(self._dynamic_stub, _UNARY_UNARY)(
_REQUEST, test_constants.LONG_TIMEOUT, protocol_options=call_options)
self.assertEqual(_RESPONSE, response)
self.assertIsNotNone(self._servicer.peer())
+ invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
+ self._servicer._invocation_metadata]
+ self.assertIn(
+ (_PER_RPC_CREDENTIALS_METADATA_KEY,
+ _PER_RPC_CREDENTIALS_METADATA_VALUE),
+ invocation_metadata)
def test_unary_stream(self):
- call_options = interfaces.grpc_call_options(disable_compression=True)
+ call_options = interfaces.grpc_call_options(
+ disable_compression=True, credentials=self._call_credentials)
response_iterator = getattr(self._dynamic_stub, _UNARY_STREAM)(
_REQUEST, test_constants.LONG_TIMEOUT, protocol_options=call_options)
self._servicer.block_until_serviced()
self.assertIsNotNone(self._servicer.peer())
+ invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
+ self._servicer._invocation_metadata]
+ self.assertIn(
+ (_PER_RPC_CREDENTIALS_METADATA_KEY,
+ _PER_RPC_CREDENTIALS_METADATA_VALUE),
+ invocation_metadata)
def test_stream_unary(self):
- call_options = interfaces.grpc_call_options()
+ call_options = interfaces.grpc_call_options(
+ credentials=self._call_credentials)
request_iterator = _BlockingIterator(iter((_REQUEST,)))
response_future = getattr(self._dynamic_stub, _STREAM_UNARY).future(
request_iterator, test_constants.LONG_TIMEOUT,
@@ -207,9 +236,16 @@ class BetaFeaturesTest(unittest.TestCase):
self._servicer.block_until_serviced()
self.assertIsNotNone(self._servicer.peer())
self.assertEqual(_RESPONSE, response_future.result())
+ invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
+ self._servicer._invocation_metadata]
+ self.assertIn(
+ (_PER_RPC_CREDENTIALS_METADATA_KEY,
+ _PER_RPC_CREDENTIALS_METADATA_VALUE),
+ invocation_metadata)
def test_stream_stream(self):
- call_options = interfaces.grpc_call_options()
+ call_options = interfaces.grpc_call_options(
+ credentials=self._call_credentials)
request_iterator = _BlockingIterator(iter((_REQUEST,)))
response_iterator = getattr(self._dynamic_stub, _STREAM_STREAM)(
request_iterator, test_constants.SHORT_TIMEOUT,
@@ -222,6 +258,12 @@ class BetaFeaturesTest(unittest.TestCase):
self._servicer.block_until_serviced()
self.assertIsNotNone(self._servicer.peer())
self.assertEqual(_RESPONSE, response)
+ invocation_metadata = [(metadatum.key, metadatum.value) for metadatum in
+ self._servicer._invocation_metadata]
+ self.assertIn(
+ (_PER_RPC_CREDENTIALS_METADATA_KEY,
+ _PER_RPC_CREDENTIALS_METADATA_VALUE),
+ invocation_metadata)
class ContextManagementAndLifecycleTest(unittest.TestCase):
@@ -250,7 +292,7 @@ class ContextManagementAndLifecycleTest(unittest.TestCase):
thread_pool_size=test_constants.POOL_SIZE)
self._server_credentials = implementations.ssl_server_credentials(
[(resources.private_key(), resources.certificate_chain(),),])
- self._client_credentials = implementations.ssl_client_credentials(
+ self._channel_credentials = implementations.ssl_channel_credentials(
resources.test_root_certificates(), None, None)
self._stub_options = implementations.stub_options(
thread_pool_size=test_constants.POOL_SIZE)
@@ -262,7 +304,7 @@ class ContextManagementAndLifecycleTest(unittest.TestCase):
server.start()
channel = test_utilities.not_really_secure_channel(
- 'localhost', port, self._client_credentials, _SERVER_HOST_OVERRIDE)
+ 'localhost', port, self._channel_credentials, _SERVER_HOST_OVERRIDE)
dynamic_stub = implementations.dynamic_stub(
channel, _GROUP, self._cardinalities, options=self._stub_options)
for _ in range(100):
diff --git a/src/python/grpcio/tests/unit/beta/_face_interface_test.py b/src/python/grpcio/tests/unit/beta/_face_interface_test.py
index 55c0d200604..1c21dfd03d5 100644
--- a/src/python/grpcio/tests/unit/beta/_face_interface_test.py
+++ b/src/python/grpcio/tests/unit/beta/_face_interface_test.py
@@ -91,10 +91,10 @@ class _Implementation(test_interfaces.Implementation):
[(resources.private_key(), resources.certificate_chain(),),])
port = server.add_secure_port('[::]:0', server_credentials)
server.start()
- client_credentials = implementations.ssl_client_credentials(
+ channel_credentials = implementations.ssl_channel_credentials(
resources.test_root_certificates(), None, None)
channel = test_utilities.not_really_secure_channel(
- 'localhost', port, client_credentials, _SERVER_HOST_OVERRIDE)
+ 'localhost', port, channel_credentials, _SERVER_HOST_OVERRIDE)
stub_options = implementations.stub_options(
request_serializers=serialization_behaviors.request_serializers,
response_deserializers=serialization_behaviors.response_deserializers,
diff --git a/src/python/grpcio/tests/unit/beta/test_utilities.py b/src/python/grpcio/tests/unit/beta/test_utilities.py
index 24a8600e12b..0313e06a93e 100644
--- a/src/python/grpcio/tests/unit/beta/test_utilities.py
+++ b/src/python/grpcio/tests/unit/beta/test_utilities.py
@@ -34,13 +34,13 @@ from grpc.beta import implementations
def not_really_secure_channel(
- host, port, client_credentials, server_host_override):
+ host, port, channel_credentials, server_host_override):
"""Creates an insecure Channel to a remote host.
Args:
host: The name of the remote host to which to connect.
port: The port of the remote host to which to connect.
- client_credentials: The implementations.ClientCredentials with which to
+ channel_credentials: The implementations.ChannelCredentials with which to
connect.
server_host_override: The target name used for SSL host name checking.
@@ -50,7 +50,7 @@ def not_really_secure_channel(
"""
hostport = '%s:%d' % (host, port)
intermediary_low_channel = _intermediary_low.Channel(
- hostport, client_credentials._intermediary_low_credentials,
+ hostport, channel_credentials._low_credentials,
server_host_override=server_host_override)
return implementations.Channel(
intermediary_low_channel._internal, intermediary_low_channel)
diff --git a/src/ruby/bin/math.proto b/src/ruby/bin/math.proto
deleted file mode 100755
index 311e148c021..00000000000
--- a/src/ruby/bin/math.proto
+++ /dev/null
@@ -1,80 +0,0 @@
-
-// Copyright 2015, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-syntax = "proto3";
-
-package math;
-
-message DivArgs {
- int64 dividend = 1;
- int64 divisor = 2;
-}
-
-message DivReply {
- int64 quotient = 1;
- int64 remainder = 2;
-}
-
-message FibArgs {
- int64 limit = 1;
-}
-
-message Num {
- int64 num = 1;
-}
-
-message FibReply {
- int64 count = 1;
-}
-
-service Math {
- // Div divides args.dividend by args.divisor and returns the quotient and
- // remainder.
- rpc Div (DivArgs) returns (DivReply) {
- }
-
- // DivMany accepts an arbitrary number of division args from the client stream
- // and sends back the results in the reply stream. The stream continues until
- // the client closes its end; the server does the same after sending all the
- // replies. The stream ends immediately if either end aborts.
- rpc DivMany (stream DivArgs) returns (stream DivReply) {
- }
-
- // Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib
- // generates up to limit numbers; otherwise it continues until the call is
- // canceled. Unlike Fib above, Fib has no final FibReply.
- rpc Fib (FibArgs) returns (stream Num) {
- }
-
- // Sum sums a stream of numbers, returning the final result once the stream
- // is closed.
- rpc Sum (stream Num) returns (Num) {
- }
-}
diff --git a/src/ruby/bin/math.rb b/src/ruby/bin/math.rb
index 323993ed439..60429a15052 100755
--- a/src/ruby/bin/math.rb
+++ b/src/ruby/bin/math.rb
@@ -1,32 +1,3 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: math.proto
diff --git a/src/ruby/bin/math_services.rb b/src/ruby/bin/math_services.rb
index cf58a53913f..2d482129c2a 100755
--- a/src/ruby/bin/math_services.rb
+++ b/src/ruby/bin/math_services.rb
@@ -1,32 +1,3 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# Source: math.proto for package 'math'
diff --git a/src/ruby/pb/README.md b/src/ruby/pb/README.md
index 84644e10988..e04aef185ca 100644
--- a/src/ruby/pb/README.md
+++ b/src/ruby/pb/README.md
@@ -20,7 +20,7 @@ re-generate the surface.
```bash
$ # (from this directory)
-$ protoc -I . grpc/health/v1alpha/health.proto \
+$ protoc -I ../../proto ../../proto/grpc/health/v1alpha/health.proto \
--grpc_out=. \
--ruby_out=. \
--plugin=protoc-gen-grpc=`which grpc_ruby_plugin`
diff --git a/src/python/grpcio/grpc/_cython/adapter_low.py b/src/ruby/pb/generate_proto_ruby.sh
old mode 100644
new mode 100755
similarity index 50%
rename from src/python/grpcio/grpc/_cython/adapter_low.py
rename to src/ruby/pb/generate_proto_ruby.sh
index 4f24da330f5..576b1c08d30
--- a/src/python/grpcio/grpc/_cython/adapter_low.py
+++ b/src/ruby/pb/generate_proto_ruby.sh
@@ -1,3 +1,4 @@
+#!/bin/sh
# Copyright 2015, Google Inc.
# All rights reserved.
#
@@ -27,76 +28,24 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# Regenerates gRPC service stubs from proto files.
+set +e
+cd $(dirname $0)/../../..
-# Adapter from grpc._cython.types to the surface expected by
-# grpc._adapter._intermediary_low.
-#
-# TODO(atash): Once this is plugged into grpc._adapter._intermediary_low, remove
-# both grpc._adapter._intermediary_low and this file. The fore and rear links in
-# grpc._adapter should be able to use grpc._cython.types directly.
-
-from grpc._adapter import _types as type_interfaces
-from grpc._cython import cygrpc
-
-
-class ClientCredentials(object):
- def __init__(self):
- raise NotImplementedError()
-
- @staticmethod
- def google_default():
- raise NotImplementedError()
-
- @staticmethod
- def ssl():
- raise NotImplementedError()
-
- @staticmethod
- def composite():
- raise NotImplementedError()
-
- @staticmethod
- def compute_engine():
- raise NotImplementedError()
-
- @staticmethod
- def jwt():
- raise NotImplementedError()
-
- @staticmethod
- def refresh_token():
- raise NotImplementedError()
-
- @staticmethod
- def iam():
- raise NotImplementedError()
-
-
-class ServerCredentials(object):
- def __init__(self):
- raise NotImplementedError()
-
- @staticmethod
- def ssl():
- raise NotImplementedError()
-
-
-class CompletionQueue(type_interfaces.CompletionQueue):
- def __init__(self):
- raise NotImplementedError()
-
-
-class Call(type_interfaces.Call):
- def __init__(self):
- raise NotImplementedError()
-
-
-class Channel(type_interfaces.Channel):
- def __init__(self):
- raise NotImplementedError()
+PROTOC=bins/opt/protobuf/protoc
+PLUGIN=protoc-gen-grpc=bins/opt/grpc_ruby_plugin
+$PROTOC -I src/proto src/proto/grpc/health/v1alpha/health.proto \
+ --grpc_out=src/ruby/pb \
+ --ruby_out=src/ruby/pb \
+ --plugin=$PLUGIN
-class Server(type_interfaces.Server):
- def __init__(self):
- raise NotImplementedError()
+$PROTOC -I . test/proto/{messages,test,empty}.proto \
+ --grpc_out=src/ruby/pb \
+ --ruby_out=src/ruby/pb \
+ --plugin=$PLUGIN
+$PROTOC -I src/proto/math src/proto/math/math.proto \
+ --grpc_out=src/ruby/bin \
+ --ruby_out=src/ruby/bin \
+ --plugin=$PLUGIN
diff --git a/src/ruby/pb/test/proto/messages.rb b/src/ruby/pb/test/proto/messages.rb
index 9b7f9772859..5222c9824a7 100644
--- a/src/ruby/pb/test/proto/messages.rb
+++ b/src/ruby/pb/test/proto/messages.rb
@@ -6,7 +6,7 @@ require 'google/protobuf'
Google::Protobuf::DescriptorPool.generated_pool.build do
add_message "grpc.testing.Payload" do
optional :type, :enum, 1, "grpc.testing.PayloadType"
- optional :body, :string, 2
+ optional :body, :bytes, 2
end
add_message "grpc.testing.EchoStatus" do
optional :code, :int32, 1
diff --git a/test/core/bad_client/gen_build_yaml.py b/test/core/bad_client/gen_build_yaml.py
index 86ada9896b0..bdb0176ba97 100755
--- a/test/core/bad_client/gen_build_yaml.py
+++ b/test/core/bad_client/gen_build_yaml.py
@@ -41,8 +41,9 @@ default_test_options = TestOptions(False)
# maps test names to options
BAD_CLIENT_TESTS = {
'connection_prefix': default_test_options,
- 'initial_settings_frame': default_test_options,
'headers': default_test_options,
+ 'initial_settings_frame': default_test_options,
+ 'unknown_frame': default_test_options,
}
def main():
diff --git a/test/core/bad_client/tests/headers.c b/test/core/bad_client/tests/headers.c
index 1d18a8241a7..5547aca210d 100644
--- a/test/core/bad_client/tests/headers.c
+++ b/test/core/bad_client/tests/headers.c
@@ -94,6 +94,22 @@ int main(int argc, char **argv) {
"\x00\x00\x04\x01\x24\x00\x00\x00\x01"
"\x00\x00\x00\x00",
0);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x05\x01\x24\x00\x00\x00\x01"
+ "\x00\x00\x00\x00",
+ GRPC_BAD_CLIENT_DISCONNECT);
GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
"\x00\x00\x05\x01\x24\x00\x00\x00\x01"
"\x00\x00\x00\x00\x00",
@@ -106,24 +122,24 @@ int main(int argc, char **argv) {
0);
GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
"\x00\x00\x04\x01\x04\x00\x00\x00\x01"
- "\x7f\x7f\x01a",
+ "\x7f\x7f\x01""a",
0);
GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
"\x00\x00\x04\x01\x04\x00\x00\x00\x01"
- "\x0f\x7f\x01a",
+ "\x0f\x7f\x01""a",
0);
GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
"\x00\x00\x04\x01\x04\x00\x00\x00\x01"
- "\x1f\x7f\x01a",
+ "\x1f\x7f\x01""a",
0);
/* test nvr, not indexed in static table */
GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
"\x00\x00\x03\x01\x04\x00\x00\x00\x01"
- "\x01\x01a",
+ "\x01\x01""a",
GRPC_BAD_CLIENT_DISCONNECT);
GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
"\x00\x00\x03\x01\x04\x00\x00\x00\x01"
- "\x11\x01a",
+ "\x11\x01""a",
GRPC_BAD_CLIENT_DISCONNECT);
/* illegal op code */
GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
@@ -195,5 +211,11 @@ int main(int argc, char **argv) {
"\x00\x00\x00\x09\x04\x00\x00\x00\x01",
0);
+ /* an invalid header found with fuzzing */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier,
+ PFX_STR
+ "\x00\x00\x00\x01\x39\x67\xed\x1d\x64",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
return 0;
}
diff --git a/src/python/grpcio/grpc/_adapter/_c/types.c b/test/core/bad_client/tests/unknown_frame.c
similarity index 67%
rename from src/python/grpcio/grpc/_adapter/_c/types.c
rename to test/core/bad_client/tests/unknown_frame.c
index 8dedf5902b3..8ea81390c94 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types.c
+++ b/test/core/bad_client/tests/unknown_frame.c
@@ -31,31 +31,28 @@
*
*/
-#include "grpc/_adapter/_c/types.h"
+#include "test/core/bad_client/bad_client.h"
+#include "src/core/surface/server.h"
-#define PY_SSIZE_T_CLEAN
-#include
-#include
+#define PFX_STR \
+ "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" \
+ "\x00\x00\x00\x04\x00\x00\x00\x00\x00"
-int pygrpc_module_add_types(PyObject *module) {
- int i;
- PyTypeObject *types[] = {
- &pygrpc_CallCredentials_type,
- &pygrpc_ChannelCredentials_type,
- &pygrpc_ServerCredentials_type,
- &pygrpc_CompletionQueue_type,
- &pygrpc_Call_type,
- &pygrpc_Channel_type,
- &pygrpc_Server_type
- };
- for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) {
- if (PyType_Ready(types[i]) < 0) {
- return -1;
- }
- }
- for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) {
- Py_INCREF(types[i]);
- PyModule_AddObject(module, types[i]->tp_name, (PyObject *)types[i]);
+static void verifier(grpc_server *server, grpc_completion_queue *cq) {
+ while (grpc_server_has_open_connections(server)) {
+ GPR_ASSERT(grpc_completion_queue_next(
+ cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20), NULL)
+ .type == GRPC_QUEUE_TIMEOUT);
}
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ /* test adding prioritization data */
+ GRPC_RUN_BAD_CLIENT_TEST(verifier, PFX_STR
+ "\x00\x00\x00\x88\x00\x00\x00\x00\x01",
+ GRPC_BAD_CLIENT_DISCONNECT);
+
return 0;
}
diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c
index 1d202f06186..9e0e22c24b8 100644
--- a/test/core/support/slice_test.c
+++ b/test/core/support/slice_test.c
@@ -94,12 +94,27 @@ static void do_nothing_with_len_1(void *ignored, size_t len) {
static void test_slice_new_with_len_returns_something_sensible(void) {
gpr_uint8 x;
+ int num_refs = 5; /* To test adding/removing an arbitrary number of refs */
+ int i;
gpr_slice slice = gpr_slice_new_with_len(&x, 1, do_nothing_with_len_1);
- GPR_ASSERT(slice.refcount);
+ GPR_ASSERT(slice.refcount); /* ref count is initialized to 1 at this point */
GPR_ASSERT(slice.data.refcounted.bytes == &x);
GPR_ASSERT(slice.data.refcounted.length == 1);
GPR_ASSERT(do_nothing_with_len_1_calls == 0);
+
+ /* Add an arbitrary number of refs to the slice and remoe the refs. This is to
+ make sure that that the destroy callback (i.e do_nothing_with_len_1()) is
+ not called until the last unref operation */
+ for (i = 0; i < num_refs; i++) {
+ gpr_slice_ref(slice);
+ }
+ for (i = 0; i < num_refs; i++) {
+ gpr_slice_unref(slice);
+ }
+ GPR_ASSERT(do_nothing_with_len_1_calls == 0); /* Shouldn't be called yet */
+
+ /* last unref */
gpr_slice_unref(slice);
GPR_ASSERT(do_nothing_with_len_1_calls == 1);
}
diff --git a/test/core/support/sync_test.c b/test/core/support/sync_test.c
index 220b16b60f5..6bc5f792e52 100644
--- a/test/core/support/sync_test.c
+++ b/test/core/support/sync_test.c
@@ -153,6 +153,7 @@ struct test {
gpr_int64 counter;
int thread_count; /* used to allocate thread ids */
int done; /* threads not yet completed */
+ int incr_step; /* how much to increment/decrement refcount each time */
gpr_mu mu; /* protects iterations, counter, thread_count, done */
@@ -170,13 +171,14 @@ struct test {
};
/* Return pointer to a new struct test. */
-static struct test *test_new(int threads, gpr_int64 iterations) {
+static struct test *test_new(int threads, gpr_int64 iterations, int incr_step) {
struct test *m = gpr_malloc(sizeof(*m));
m->threads = threads;
m->iterations = iterations;
m->counter = 0;
m->thread_count = 0;
m->done = threads;
+ m->incr_step = incr_step;
gpr_mu_init(&m->mu);
gpr_cv_init(&m->cv);
gpr_cv_init(&m->done_cv);
@@ -238,9 +240,12 @@ static void mark_thread_done(struct test *m) {
/* Test several threads running (*body)(struct test *m) for increasing settings
of m->iterations, until about timeout_s to 2*timeout_s seconds have elapsed.
- If extra!=NULL, run (*extra)(m) in an additional thread. */
+ If extra!=NULL, run (*extra)(m) in an additional thread.
+ incr_step controls by how much m->refcount should be incremented/decremented
+ (if at all) each time in the tests.
+ */
static void test(const char *name, void (*body)(void *m),
- void (*extra)(void *m), int timeout_s) {
+ void (*extra)(void *m), int timeout_s, int incr_step) {
gpr_int64 iterations = 1024;
struct test *m;
gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME);
@@ -251,7 +256,7 @@ static void test(const char *name, void (*body)(void *m),
while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) {
iterations <<= 1;
fprintf(stderr, " %ld", (long)iterations);
- m = test_new(10, iterations);
+ m = test_new(10, iterations, incr_step);
if (extra != NULL) {
gpr_thd_id id;
GPR_ASSERT(gpr_thd_new(&id, extra, m, NULL));
@@ -259,7 +264,7 @@ static void test(const char *name, void (*body)(void *m),
}
test_create_threads(m, body);
test_wait(m);
- if (m->counter != m->threads * m->iterations) {
+ if (m->counter != m->threads * m->iterations * m->incr_step) {
fprintf(stderr, "counter %ld threads %d iterations %ld\n",
(long)m->counter, m->threads, (long)m->iterations);
GPR_ASSERT(0);
@@ -406,14 +411,18 @@ static void statsinc(void *v /*=m*/) {
mark_thread_done(m);
}
-/* Increment m->refcount m->iterations times, decrement m->thread_refcount
- once, and if it reaches zero, set m->event to (void*)1; then mark thread as
- done. */
+/* Increment m->refcount by m->incr_step for m->iterations times. Decrement
+ m->thread_refcount once, and if it reaches zero, set m->event to (void*)1;
+ then mark thread as done. */
static void refinc(void *v /*=m*/) {
struct test *m = v;
gpr_int64 i;
for (i = 0; i != m->iterations; i++) {
- gpr_ref(&m->refcount);
+ if (m->incr_step == 1) {
+ gpr_ref(&m->refcount);
+ } else {
+ gpr_refn(&m->refcount, m->incr_step);
+ }
}
if (gpr_unref(&m->thread_refcount)) {
gpr_event_set(&m->event, (void *)1);
@@ -421,12 +430,13 @@ static void refinc(void *v /*=m*/) {
mark_thread_done(m);
}
-/* Wait until m->event is set to (void *)1, then decrement m->refcount
- m->stats_counter m->iterations times, and ensure that the last decrement
- caused the counter to reach zero, then mark thread as done. */
+
+/* Wait until m->event is set to (void *)1, then decrement m->refcount by 1
+ (m->threads * m->iterations * m->incr_step) times, and ensure that the last
+ decrement caused the counter to reach zero, then mark thread as done. */
static void refcheck(void *v /*=m*/) {
struct test *m = v;
- gpr_int64 n = m->iterations * m->threads;
+ gpr_int64 n = m->iterations * m->threads * m->incr_step;
gpr_int64 i;
GPR_ASSERT(gpr_event_wait(&m->event, gpr_inf_future(GPR_CLOCK_REALTIME)) ==
(void *)1);
@@ -444,13 +454,16 @@ static void refcheck(void *v /*=m*/) {
int main(int argc, char *argv[]) {
grpc_test_init(argc, argv);
- test("mutex", &inc, NULL, 1);
- test("mutex try", &inctry, NULL, 1);
- test("cv", &inc_by_turns, NULL, 1);
- test("timedcv", &inc_with_1ms_delay, NULL, 1);
- test("queue", &many_producers, &consumer, 10);
- test("stats_counter", &statsinc, NULL, 1);
- test("refcount", &refinc, &refcheck, 1);
- test("timedevent", &inc_with_1ms_delay_event, NULL, 1);
+ test("mutex", &inc, NULL, 1, 1);
+ test("mutex try", &inctry, NULL, 1, 1);
+ test("cv", &inc_by_turns, NULL, 1, 1);
+ test("timedcv", &inc_with_1ms_delay, NULL, 1, 1);
+ test("queue", &many_producers, &consumer, 10, 1);
+ test("stats_counter", &statsinc, NULL, 1, 1);
+ test("refcount by 1", &refinc, &refcheck, 1, 1);
+ test("refcount by 3", &refinc, &refcheck, 1, 3); /* incr_step of 3 is an
+ arbitrary choice. Any
+ number > 1 is okay here */
+ test("timedevent", &inc_with_1ms_delay_event, NULL, 1, 1);
return 0;
}
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index e3fc7897884..7a5cf30506f 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -175,6 +175,19 @@ static void test_pluck(void) {
grpc_exec_ctx_finish(&exec_ctx);
}
+static void test_pluck_after_shutdown(void) {
+ grpc_event ev;
+ grpc_completion_queue *cc;
+
+ LOG_TEST("test_pluck_after_shutdown");
+ cc = grpc_completion_queue_create(NULL);
+ grpc_completion_queue_shutdown(cc);
+ ev = grpc_completion_queue_pluck(cc, NULL, gpr_inf_future(GPR_CLOCK_REALTIME),
+ NULL);
+ GPR_ASSERT(ev.type == GRPC_QUEUE_SHUTDOWN);
+ grpc_completion_queue_destroy(cc);
+}
+
#define TEST_THREAD_EVENTS 10000
typedef struct test_thread_options {
@@ -343,6 +356,7 @@ int main(int argc, char **argv) {
test_shutdown_then_next_with_timeout();
test_cq_end_op();
test_pluck();
+ test_pluck_after_shutdown();
test_threading(1, 1);
test_threading(1, 10);
test_threading(10, 1);
diff --git a/test/core/surface/init_test.c b/test/core/surface/init_test.c
index c8791965bfd..d4451e45672 100644
--- a/test/core/surface/init_test.c
+++ b/test/core/surface/init_test.c
@@ -47,7 +47,7 @@ static void test(int rounds) {
}
}
-static void test_mixed() {
+static void test_mixed(void) {
grpc_init();
grpc_init();
grpc_shutdown();
@@ -56,8 +56,8 @@ static void test_mixed() {
grpc_shutdown();
}
-static void plugin_init() { g_flag = 1; }
-static void plugin_destroy() { g_flag = 2; }
+static void plugin_init(void) { g_flag = 1; }
+static void plugin_destroy(void) { g_flag = 2; }
static void test_plugin() {
grpc_register_plugin(plugin_init, plugin_destroy);
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index f2ed1a205b6..3386c429ffe 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -14313,6 +14313,21 @@
"test/core/bad_client/tests/initial_settings_frame.c"
]
},
+ {
+ "deps": [
+ "bad_client_test",
+ "gpr",
+ "gpr_test_util",
+ "grpc_test_util_unsecure",
+ "grpc_unsecure"
+ ],
+ "headers": [],
+ "language": "c",
+ "name": "unknown_frame_bad_client_test",
+ "src": [
+ "test/core/bad_client/tests/unknown_frame.c"
+ ]
+ },
{
"deps": [],
"headers": [
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index e5c7c701611..145ba781422 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -15554,5 +15554,23 @@
"posix",
"windows"
]
+ },
+ {
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "exclude_configs": [],
+ "flaky": false,
+ "language": "c",
+ "name": "unknown_frame_bad_client_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ]
}
]
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index 8a72aa408fe..3762b2fce61 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -10047,6 +10047,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "initial_settings_frame_bad_
{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
EndProjectSection
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unknown_frame_bad_client_test", "vcxproj\test\unknown_frame_bad_client_test\unknown_frame_bad_client_test.vcxproj", "{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}"
+ ProjectSection(myProperties) = preProject
+ lib = "False"
+ EndProjectSection
+ ProjectSection(ProjectDependencies) = postProject
+ {BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+ {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+ {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -22411,6 +22423,22 @@ Global
{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|Win32.Build.0 = Release|Win32
{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|x64.ActiveCfg = Release|x64
{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|x64.Build.0 = Release|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug|x64.ActiveCfg = Debug|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release|Win32.ActiveCfg = Release|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release|x64.ActiveCfg = Release|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug|Win32.Build.0 = Debug|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug|x64.Build.0 = Debug|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release|Win32.Build.0 = Release|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release|x64.Build.0 = Release|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug-DLL|Win32.Build.0 = Debug|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug-DLL|x64.ActiveCfg = Debug|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug-DLL|x64.Build.0 = Debug|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release-DLL|Win32.ActiveCfg = Release|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release-DLL|Win32.Build.0 = Release|Win32
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release-DLL|x64.ActiveCfg = Release|x64
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release-DLL|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/vsprojects/vcxproj/test/unknown_frame_bad_client_test/unknown_frame_bad_client_test.vcxproj b/vsprojects/vcxproj/test/unknown_frame_bad_client_test/unknown_frame_bad_client_test.vcxproj
new file mode 100644
index 00000000000..21104cafe64
--- /dev/null
+++ b/vsprojects/vcxproj/test/unknown_frame_bad_client_test/unknown_frame_bad_client_test.vcxproj
@@ -0,0 +1,187 @@
+
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}
+
+
+
+ v100
+
+
+ v110
+
+
+ v120
+
+
+ Application
+ true
+ Unicode
+
+
+ Application
+ false
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+ unknown_frame_bad_client_test
+ static
+ Debug
+ Debug
+
+
+ unknown_frame_bad_client_test
+ static
+ Debug
+ Debug
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ true
+ None
+
+
+ Console
+ true
+ false
+
+
+
+
+ NotUsing
+ Level3
+ Disabled
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ MultiThreadedDebug
+ true
+ None
+
+
+ Console
+ true
+ false
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ None
+
+
+ Console
+ true
+ false
+ true
+ true
+
+
+
+
+ Level3
+ NotUsing
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ MultiThreaded
+ true
+ None
+
+
+ Console
+ true
+ false
+ true
+ true
+
+
+
+
+
+
+
+
+ {BA67B418-B699-E41A-9CC4-0279C49481A5}
+
+
+ {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+
+
+ {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+
+
+ {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+
+
+ {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
+
+
+
+
diff --git a/vsprojects/vcxproj/test/unknown_frame_bad_client_test/unknown_frame_bad_client_test.vcxproj.filters b/vsprojects/vcxproj/test/unknown_frame_bad_client_test/unknown_frame_bad_client_test.vcxproj.filters
new file mode 100644
index 00000000000..d585856331f
--- /dev/null
+++ b/vsprojects/vcxproj/test/unknown_frame_bad_client_test/unknown_frame_bad_client_test.vcxproj.filters
@@ -0,0 +1,24 @@
+
+
+
+
+ test\core\bad_client\tests
+
+
+
+
+
+ {77ca54f4-deb2-3a34-5548-0a2bc7cbacc1}
+
+
+ {2e30ac00-932d-ab0d-fabf-e0ea035aae46}
+
+
+ {527abde4-b314-c50f-b007-dd3fdb2445ba}
+
+
+ {691de782-c331-3836-ac26-43873334f0c0}
+
+
+
+