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} + + + +