diff --git a/Makefile b/Makefile index 3e1efc7646a..d9e1f35cba7 100644 --- a/Makefile +++ b/Makefile @@ -556,6 +556,7 @@ async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test credentials_test: $(BINDIR)/$(CONFIG)/credentials_test end2end_test: $(BINDIR)/$(CONFIG)/end2end_test +generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin @@ -986,7 +987,7 @@ buildtests: buildtests_c buildtests_cxx buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_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_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_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_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_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_stream_op_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)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_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)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test -buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test +buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test test: test_c test_cxx @@ -1822,6 +1823,8 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 ) $(E) "[RUN] Testing end2end_test" $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing generic_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing interop_test" $(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 ) $(E) "[RUN] Testing pubsub_publisher_test" @@ -3126,17 +3129,22 @@ LIBGRPC++_SRC = \ src/cpp/common/completion_queue.cc \ src/cpp/common/rpc_method.cc \ src/cpp/proto/proto_utils.cc \ + src/cpp/server/async_generic_service.cc \ src/cpp/server/insecure_server_credentials.cc \ src/cpp/server/server.cc \ src/cpp/server/server_builder.cc \ src/cpp/server/server_context.cc \ src/cpp/server/server_credentials.cc \ src/cpp/server/thread_pool.cc \ + src/cpp/util/byte_buffer.cc \ + src/cpp/util/slice.cc \ src/cpp/util/status.cc \ src/cpp/util/time.cc \ PUBLIC_HEADERS_CXX += \ + include/grpc++/async_generic_service.h \ include/grpc++/async_unary_call.h \ + include/grpc++/byte_buffer.h \ include/grpc++/channel_arguments.h \ include/grpc++/channel_interface.h \ include/grpc++/client_context.h \ @@ -3154,6 +3162,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/server_builder.h \ include/grpc++/server_context.h \ include/grpc++/server_credentials.h \ + include/grpc++/slice.h \ include/grpc++/status.h \ include/grpc++/status_code_enum.h \ include/grpc++/stream.h \ @@ -3207,12 +3216,15 @@ src/cpp/common/call.cc: $(OPENSSL_DEP) src/cpp/common/completion_queue.cc: $(OPENSSL_DEP) src/cpp/common/rpc_method.cc: $(OPENSSL_DEP) src/cpp/proto/proto_utils.cc: $(OPENSSL_DEP) +src/cpp/server/async_generic_service.cc: $(OPENSSL_DEP) src/cpp/server/insecure_server_credentials.cc: $(OPENSSL_DEP) src/cpp/server/server.cc: $(OPENSSL_DEP) src/cpp/server/server_builder.cc: $(OPENSSL_DEP) src/cpp/server/server_context.cc: $(OPENSSL_DEP) src/cpp/server/server_credentials.cc: $(OPENSSL_DEP) src/cpp/server/thread_pool.cc: $(OPENSSL_DEP) +src/cpp/util/byte_buffer.cc: $(OPENSSL_DEP) +src/cpp/util/slice.cc: $(OPENSSL_DEP) src/cpp/util/status.cc: $(OPENSSL_DEP) src/cpp/util/time.cc: $(OPENSSL_DEP) endif @@ -3270,12 +3282,15 @@ $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: $(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/async_generic_service.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/thread_pool.o: +$(OBJDIR)/$(CONFIG)/src/cpp/util/byte_buffer.o: +$(OBJDIR)/$(CONFIG)/src/cpp/util/slice.o: $(OBJDIR)/$(CONFIG)/src/cpp/util/status.o: $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: @@ -3358,17 +3373,22 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/common/completion_queue.cc \ src/cpp/common/rpc_method.cc \ src/cpp/proto/proto_utils.cc \ + src/cpp/server/async_generic_service.cc \ src/cpp/server/insecure_server_credentials.cc \ src/cpp/server/server.cc \ src/cpp/server/server_builder.cc \ src/cpp/server/server_context.cc \ src/cpp/server/server_credentials.cc \ src/cpp/server/thread_pool.cc \ + src/cpp/util/byte_buffer.cc \ + src/cpp/util/slice.cc \ src/cpp/util/status.cc \ src/cpp/util/time.cc \ PUBLIC_HEADERS_CXX += \ + include/grpc++/async_generic_service.h \ include/grpc++/async_unary_call.h \ + include/grpc++/byte_buffer.h \ include/grpc++/channel_arguments.h \ include/grpc++/channel_interface.h \ include/grpc++/client_context.h \ @@ -3386,6 +3406,7 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/server_builder.h \ include/grpc++/server_context.h \ include/grpc++/server_credentials.h \ + include/grpc++/slice.h \ include/grpc++/status.h \ include/grpc++/status_code_enum.h \ include/grpc++/stream.h \ @@ -3454,12 +3475,15 @@ $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: $(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/async_generic_service.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/thread_pool.o: +$(OBJDIR)/$(CONFIG)/src/cpp/util/byte_buffer.o: +$(OBJDIR)/$(CONFIG)/src/cpp/util/slice.o: $(OBJDIR)/$(CONFIG)/src/cpp/util/status.o: $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: @@ -7944,6 +7968,48 @@ endif endif +GENERIC_END2END_TEST_SRC = \ + test/cpp/end2end/generic_end2end_test.cc \ + +GENERIC_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GENERIC_END2END_TEST_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL with ALPN. + +$(BINDIR)/$(CONFIG)/generic_end2end_test: openssl_dep_error + +else + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/generic_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/generic_end2end_test: $(PROTOBUF_DEP) $(GENERIC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GENERIC_END2END_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/generic_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/generic_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_generic_end2end_test: $(GENERIC_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GENERIC_END2END_TEST_OBJS:.o=.dep) +endif +endif + + GRPC_CPP_PLUGIN_SRC = \ src/compiler/cpp_generator.cc \ src/compiler/cpp_plugin.cc \ diff --git a/build.json b/build.json index c9500ebe1bd..999e140c5a1 100644 --- a/build.json +++ b/build.json @@ -12,7 +12,9 @@ { "name": "grpc++_base", "public_headers": [ + "include/grpc++/async_generic_service.h", "include/grpc++/async_unary_call.h", + "include/grpc++/byte_buffer.h", "include/grpc++/channel_arguments.h", "include/grpc++/channel_interface.h", "include/grpc++/client_context.h", @@ -30,6 +32,7 @@ "include/grpc++/server_builder.h", "include/grpc++/server_context.h", "include/grpc++/server_credentials.h", + "include/grpc++/slice.h", "include/grpc++/status.h", "include/grpc++/status_code_enum.h", "include/grpc++/stream.h", @@ -54,12 +57,15 @@ "src/cpp/common/completion_queue.cc", "src/cpp/common/rpc_method.cc", "src/cpp/proto/proto_utils.cc", + "src/cpp/server/async_generic_service.cc", "src/cpp/server/insecure_server_credentials.cc", "src/cpp/server/server.cc", "src/cpp/server/server_builder.cc", "src/cpp/server/server_context.cc", "src/cpp/server/server_credentials.cc", "src/cpp/server/thread_pool.cc", + "src/cpp/util/byte_buffer.cc", + "src/cpp/util/slice.cc", "src/cpp/util/status.cc", "src/cpp/util/time.cc" ] @@ -1698,6 +1704,22 @@ "gpr" ] }, + { + "name": "generic_end2end_test", + "build": "test", + "language": "c++", + "src": [ + "test/cpp/end2end/generic_end2end_test.cc" + ], + "deps": [ + "grpc++_test_util", + "grpc_test_util", + "grpc++", + "grpc", + "gpr_test_util", + "gpr" + ] + }, { "name": "grpc_cpp_plugin", "build": "protoc", diff --git a/include/grpc++/async_generic_service.h b/include/grpc++/async_generic_service.h new file mode 100644 index 00000000000..d10a56c7f78 --- /dev/null +++ b/include/grpc++/async_generic_service.h @@ -0,0 +1,79 @@ +/* + * + * 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 GRPCXX_ASYNC_GENERIC_SERVICE_H +#define GRPCXX_ASYNC_GENERIC_SERVICE_H + +#include +#include + +struct grpc_server; + +namespace grpc { + +typedef ServerAsyncReaderWriter GenericServerAsyncReaderWriter; + +class GenericServerContext GRPC_FINAL : public ServerContext { + public: + const grpc::string& method() const { return method_; } + const grpc::string& host() const { return host_; } + + private: + friend class Server; + + grpc::string method_; + grpc::string host_; +}; + +class AsyncGenericService GRPC_FINAL { + public: + // TODO(yangg) Once we can add multiple completion queues to the server + // in c core, add a CompletionQueue* argument to the ctor here. + // TODO(yangg) support methods list. + AsyncGenericService(const grpc::string& methods) : server_(nullptr) {} + + void RequestCall(GenericServerContext* ctx, + GenericServerAsyncReaderWriter* reader_writer, + CompletionQueue* cq, void* tag); + + // The new rpc event should be obtained from this completion queue. + CompletionQueue* completion_queue(); + + private: + friend class Server; + Server* server_; +}; + +} // namespace grpc + +#endif // GRPCXX_ASYNC_GENERIC_SERVICE_H diff --git a/include/grpc++/byte_buffer.h b/include/grpc++/byte_buffer.h new file mode 100644 index 00000000000..e864ca3bba2 --- /dev/null +++ b/include/grpc++/byte_buffer.h @@ -0,0 +1,84 @@ +/* + * + * 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 GRPCXX_BYTE_BUFFER_H +#define GRPCXX_BYTE_BUFFER_H + +#include +#include +#include +#include + +#include + +namespace grpc { + +class ByteBuffer GRPC_FINAL { + public: + ByteBuffer() : buffer_(nullptr) {} + + ByteBuffer(Slice* slices, size_t nslices); + + ~ByteBuffer() { + if (buffer_) { + grpc_byte_buffer_destroy(buffer_); + } + } + + void Dump(std::vector* slices); + + void Clear(); + size_t Length(); + + private: + friend class CallOpBuffer; + + // takes ownership + void set_buffer(grpc_byte_buffer* buf) { + if (buffer_) { + gpr_log(GPR_ERROR, "Overriding existing buffer"); + Clear(); + } + buffer_ = buf; + } + + grpc_byte_buffer* buffer() const { + return buffer_; + } + + grpc_byte_buffer* buffer_; +}; + +} // namespace grpc + +#endif // GRPCXX_BYTE_BUFFER_H diff --git a/include/grpc++/generic_stub.h b/include/grpc++/generic_stub.h new file mode 100644 index 00000000000..6038d7c66cc --- /dev/null +++ b/include/grpc++/generic_stub.h @@ -0,0 +1,62 @@ +/* + * + * 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 GRPCXX_GENERIC_STUB_H +#define GRPCXX_GENERIC_STUB_H + +#include +#include + +namespace grpc { + +typedef ClientAsyncReaderWriter + GenericClientAsyncReaderWriter; + +// Generic stubs provide a type-unsafe interface to call gRPC methods +// by name. +class GenericStub GRPC_FINAL { + public: + explicit GenericStub(std::shared_ptr channel) + : channel_(channel) {} + + // begin a call to a named method + std::unique_ptr Call( + ClientContext* context, const grpc::string& method); + + private: + std::shared_ptr channel_; +}; + +} // namespace grpc + +#endif // GRPCXX_GENERIC_STUB_H diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h index 5de56629735..a8551ad4595 100644 --- a/include/grpc++/impl/call.h +++ b/include/grpc++/impl/call.h @@ -35,9 +35,9 @@ #define GRPCXX_IMPL_CALL_H #include +#include #include #include -#include #include #include @@ -47,6 +47,7 @@ struct grpc_op; namespace grpc { +class ByteBuffer; class Call; class CallOpBuffer : public CompletionQueueTag { @@ -62,7 +63,9 @@ class CallOpBuffer : public CompletionQueueTag { void AddSendInitialMetadata(ClientContext *ctx); void AddRecvInitialMetadata(ClientContext *ctx); void AddSendMessage(const grpc::protobuf::Message &message); + void AddSendMessage(const ByteBuffer& message); void AddRecvMessage(grpc::protobuf::Message *message); + void AddRecvMessage(ByteBuffer *message); void AddClientSendClose(); void AddClientRecvStatus(ClientContext *ctx, Status *status); void AddServerSendStatus(std::multimap *metadata, @@ -90,10 +93,12 @@ class CallOpBuffer : public CompletionQueueTag { grpc_metadata_array recv_initial_metadata_arr_; // Send message const grpc::protobuf::Message *send_message_; - grpc_byte_buffer *send_message_buf_; + const ByteBuffer *send_message_buffer_; + grpc_byte_buffer *send_buf_; // Recv message grpc::protobuf::Message *recv_message_; - grpc_byte_buffer *recv_message_buf_; + ByteBuffer *recv_message_buffer_; + grpc_byte_buffer *recv_buf_; // Client send close bool client_send_close_; // Client recv status diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 43c8432caf5..8cd0a4f6681 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -49,6 +49,8 @@ struct grpc_server; namespace grpc { class AsynchronousService; +class GenericServerContext; +class AsyncGenericService; class RpcService; class RpcServiceMethod; class ServerCredentials; @@ -69,6 +71,7 @@ class Server GRPC_FINAL : private CallHook, void Wait(); private: + friend class AsyncGenericService; friend class ServerBuilder; class SyncRequest; @@ -81,6 +84,7 @@ class Server GRPC_FINAL : private CallHook, // The service must exist for the lifetime of the Server instance. bool RegisterService(RpcService* service); bool RegisterAsyncService(AsynchronousService* service); + void RegisterAsyncGenericService(AsyncGenericService* service); // Add a listening port. Can be called multiple times. int AddPort(const grpc::string& addr, ServerCredentials* creds); // Start the server. @@ -98,6 +102,10 @@ class Server GRPC_FINAL : private CallHook, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) GRPC_OVERRIDE; + void RequestAsyncGenericCall(GenericServerContext* context, + ServerAsyncStreamingInterface* stream, + CompletionQueue* cq, void* tag); + // Completion queue. CompletionQueue cq_; diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index a3270775637..c09c8fee52c 100644 --- a/include/grpc++/server_builder.h +++ b/include/grpc++/server_builder.h @@ -41,6 +41,7 @@ namespace grpc { +class AsyncGenericService; class AsynchronousService; class CompletionQueue; class RpcService; @@ -64,6 +65,9 @@ class ServerBuilder { // instance returned by BuildAndStart(). void RegisterAsyncService(AsynchronousService* service); + // Register a generic service. + void RegisterAsyncGenericService(AsyncGenericService* service); + // Add a listening port. Can be called multiple times. void AddPort(const grpc::string& addr, std::shared_ptr creds, @@ -87,6 +91,7 @@ class ServerBuilder { std::vector async_services_; std::vector ports_; std::shared_ptr creds_; + AsyncGenericService* generic_service_; ThreadPoolInterface* thread_pool_; }; diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h index a986fff46bf..9e3b80c6411 100644 --- a/include/grpc++/server_context.h +++ b/include/grpc++/server_context.h @@ -66,7 +66,7 @@ class CompletionQueue; class Server; // Interface of server side rpc context. -class ServerContext GRPC_FINAL { +class ServerContext { public: ServerContext(); // for async calls ~ServerContext(); diff --git a/include/grpc++/slice.h b/include/grpc++/slice.h new file mode 100644 index 00000000000..3e01bcf0ad7 --- /dev/null +++ b/include/grpc++/slice.h @@ -0,0 +1,74 @@ +/* + * + * 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 GRPCXX_SLICE_H +#define GRPCXX_SLICE_H + +#include +#include + +namespace grpc { + +class Slice GRPC_FINAL { + public: + // construct empty slice + Slice(); + // destructor - drops one ref + ~Slice(); + // construct slice from grpc slice, adding a ref + enum AddRef { ADD_REF }; + Slice(gpr_slice slice, AddRef); + // construct slice from grpc slice, stealing a ref + enum StealRef { STEAL_REF }; + Slice(gpr_slice slice, StealRef); + // copy constructor - adds a ref + Slice(const Slice& other); + // assignment - ref count is unchanged + Slice& operator=(Slice other) { + std::swap(slice_, other.slice_); + return *this; + } + + size_t size() const { return GPR_SLICE_LENGTH(slice_); } + const gpr_uint8* begin() const { return GPR_SLICE_START_PTR(slice_); } + const gpr_uint8* end() const { return GPR_SLICE_END_PTR(slice_); } + + private: + friend class ByteBuffer; + + gpr_slice slice_; +}; + +} // namespace grpc + +#endif // GRPCXX_SLICE_H diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc index 6ce1e8a7d58..ebe7deec702 100644 --- a/src/cpp/common/call.cc +++ b/src/cpp/common/call.cc @@ -31,8 +31,10 @@ * */ -#include #include + +#include +#include #include #include @@ -48,9 +50,11 @@ CallOpBuffer::CallOpBuffer() recv_initial_metadata_(nullptr), recv_initial_metadata_arr_{0, 0, nullptr}, send_message_(nullptr), - send_message_buf_(nullptr), + send_message_buffer_(nullptr), + send_buf_(nullptr), recv_message_(nullptr), - recv_message_buf_(nullptr), + recv_message_buffer_(nullptr), + recv_buf_(nullptr), client_send_close_(false), recv_trailing_metadata_(nullptr), recv_status_(nullptr), @@ -74,18 +78,20 @@ void CallOpBuffer::Reset(void* next_return_tag) { recv_initial_metadata_ = nullptr; recv_initial_metadata_arr_.count = 0; - send_message_ = nullptr; - if (send_message_buf_) { - grpc_byte_buffer_destroy(send_message_buf_); - send_message_buf_ = nullptr; + if (send_buf_ && send_message_) { + grpc_byte_buffer_destroy(send_buf_); } + send_message_ = nullptr; + send_message_buffer_ = nullptr; + send_buf_ = nullptr; - recv_message_ = nullptr; got_message = false; - if (recv_message_buf_) { - grpc_byte_buffer_destroy(recv_message_buf_); - recv_message_buf_ = nullptr; + if (recv_buf_ && recv_message_) { + grpc_byte_buffer_destroy(recv_buf_); } + recv_message_ = nullptr; + recv_message_buffer_ = nullptr; + recv_buf_ = nullptr; client_send_close_ = false; @@ -106,11 +112,11 @@ CallOpBuffer::~CallOpBuffer() { gpr_free(status_details_); gpr_free(recv_initial_metadata_arr_.metadata); gpr_free(recv_trailing_metadata_arr_.metadata); - if (recv_message_buf_) { - grpc_byte_buffer_destroy(recv_message_buf_); + if (recv_buf_ && recv_message_) { + grpc_byte_buffer_destroy(recv_buf_); } - if (send_message_buf_) { - grpc_byte_buffer_destroy(send_message_buf_); + if (send_buf_ && send_message_) { + grpc_byte_buffer_destroy(send_buf_); } } @@ -166,11 +172,19 @@ void CallOpBuffer::AddSendMessage(const grpc::protobuf::Message& message) { send_message_ = &message; } +void CallOpBuffer::AddSendMessage(const ByteBuffer& message) { + send_message_buffer_ = &message; +} + void CallOpBuffer::AddRecvMessage(grpc::protobuf::Message* message) { recv_message_ = message; recv_message_->Clear(); } +void CallOpBuffer::AddRecvMessage(ByteBuffer* message) { + recv_message_buffer_ = message; +} + void CallOpBuffer::AddClientSendClose() { client_send_close_ = true; } void CallOpBuffer::AddServerRecvClose(bool* cancelled) { @@ -206,19 +220,23 @@ void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) { ops[*nops].data.recv_initial_metadata = &recv_initial_metadata_arr_; (*nops)++; } - if (send_message_) { - bool success = SerializeProto(*send_message_, &send_message_buf_); - if (!success) { - abort(); - // TODO handle parse failure + if (send_message_ || send_message_buffer_) { + if (send_message_) { + bool success = SerializeProto(*send_message_, &send_buf_); + if (!success) { + abort(); + // TODO handle parse failure + } + } else { + send_buf_ = send_message_buffer_->buffer(); } ops[*nops].op = GRPC_OP_SEND_MESSAGE; - ops[*nops].data.send_message = send_message_buf_; + ops[*nops].data.send_message = send_buf_; (*nops)++; } - if (recv_message_) { + if (recv_message_ || recv_message_buffer_) { ops[*nops].op = GRPC_OP_RECV_MESSAGE; - ops[*nops].data.recv_message = &recv_message_buf_; + ops[*nops].data.recv_message = &recv_buf_; (*nops)++; } if (client_send_close_) { @@ -256,9 +274,11 @@ void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) { bool CallOpBuffer::FinalizeResult(void** tag, bool* status) { // Release send buffers. - if (send_message_buf_) { - grpc_byte_buffer_destroy(send_message_buf_); - send_message_buf_ = nullptr; + if (send_buf_ && send_message_) { + if (send_message_) { + grpc_byte_buffer_destroy(send_buf_); + } + send_buf_ = nullptr; } if (initial_metadata_) { gpr_free(initial_metadata_); @@ -275,12 +295,16 @@ bool CallOpBuffer::FinalizeResult(void** tag, bool* status) { FillMetadataMap(&recv_initial_metadata_arr_, recv_initial_metadata_); } // Parse received message if any. - if (recv_message_) { - if (recv_message_buf_) { + if (recv_message_ || recv_message_buffer_) { + if (recv_buf_) { got_message = *status; - *status = *status && DeserializeProto(recv_message_buf_, recv_message_); - grpc_byte_buffer_destroy(recv_message_buf_); - recv_message_buf_ = nullptr; + if (recv_message_) { + *status = *status && DeserializeProto(recv_buf_, recv_message_); + grpc_byte_buffer_destroy(recv_buf_); + } else { + recv_message_buffer_->set_buffer(recv_buf_); + } + recv_buf_ = nullptr; } else { // Read failed got_message = false; diff --git a/src/cpp/server/async_generic_service.cc b/src/cpp/server/async_generic_service.cc new file mode 100644 index 00000000000..2009af7cbd1 --- /dev/null +++ b/src/cpp/server/async_generic_service.cc @@ -0,0 +1,51 @@ +/* + * + * 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 + +namespace grpc { + +void AsyncGenericService::RequestCall( + GenericServerContext* ctx, GenericServerAsyncReaderWriter* reader_writer, + CompletionQueue* cq, void* tag) { + server_->RequestAsyncGenericCall(ctx, reader_writer, cq, tag); +} + +CompletionQueue* AsyncGenericService::completion_queue() { + return &server_->cq_; +} + +} // namespace grpc + diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 87296805652..4d5e77e6337 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -36,8 +36,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -226,6 +228,12 @@ bool Server::RegisterAsyncService(AsynchronousService* service) { return true; } +void Server::RegisterAsyncGenericService(AsyncGenericService* service) { + GPR_ASSERT(service->server_ == nullptr && + "Can only register an async generic service against one server."); + service->server_ = this; +} + int Server::AddPort(const grpc::string& addr, ServerCredentials* creds) { GPR_ASSERT(!started_); return creds->AddPortToServer(addr, server_); @@ -289,15 +297,36 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { stream_(stream), cq_(cq), ctx_(ctx), + generic_ctx_(nullptr), server_(server), call_(nullptr), payload_(nullptr) { memset(&array_, 0, sizeof(array_)); + grpc_call_details_init(&call_details_); grpc_server_request_registered_call( - server->server_, registered_method, &call_, &deadline_, &array_, - request ? &payload_ : nullptr, cq->cq(), this); + server->server_, registered_method, &call_, &call_details_.deadline, + &array_, request ? &payload_ : nullptr, cq->cq(), this); + } + + AsyncRequest(Server* server, GenericServerContext* ctx, + ServerAsyncStreamingInterface* stream, CompletionQueue* cq, + void* tag) + : tag_(tag), + request_(nullptr), + stream_(stream), + cq_(cq), + ctx_(nullptr), + generic_ctx_(ctx), + server_(server), + call_(nullptr), + payload_(nullptr) { + memset(&array_, 0, sizeof(array_)); + grpc_call_details_init(&call_details_); + grpc_server_request_call( + server->server_, &call_, &call_details_, &array_, cq->cq(), this); } + ~AsyncRequest() { if (payload_) { grpc_byte_buffer_destroy(payload_); @@ -315,20 +344,29 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { *status = false; } } + ServerContext* ctx = ctx_ ? ctx_ : generic_ctx_; + GPR_ASSERT(ctx); if (*status) { - ctx_->deadline_ = Timespec2Timepoint(deadline_); + ctx->deadline_ = Timespec2Timepoint(call_details_.deadline); for (size_t i = 0; i < array_.count; i++) { - ctx_->client_metadata_.insert(std::make_pair( + ctx->client_metadata_.insert(std::make_pair( grpc::string(array_.metadata[i].key), grpc::string( array_.metadata[i].value, array_.metadata[i].value + array_.metadata[i].value_length))); } + if (generic_ctx_) { + // TODO(yangg) remove the copy here. + generic_ctx_->method_ = call_details_.method; + generic_ctx_->host_ = call_details_.host; + gpr_free(call_details_.method); + gpr_free(call_details_.host); + } } - ctx_->call_ = call_; + ctx->call_ = call_; Call call(call_, server_, cq_); if (orig_status && call_) { - ctx_->BeginCompletionOp(&call); + ctx->BeginCompletionOp(&call); } // just the pointers inside call are copied here stream_->BindCall(&call); @@ -342,9 +380,10 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { ServerAsyncStreamingInterface* const stream_; CompletionQueue* const cq_; ServerContext* const ctx_; + GenericServerContext* const generic_ctx_; Server* const server_; grpc_call* call_; - gpr_timespec deadline_; + grpc_call_details call_details_; grpc_metadata_array array_; grpc_byte_buffer* payload_; }; @@ -356,6 +395,12 @@ void Server::RequestAsyncCall(void* registered_method, ServerContext* context, new AsyncRequest(this, registered_method, context, request, stream, cq, tag); } +void Server::RequestAsyncGenericCall(GenericServerContext* context, + ServerAsyncStreamingInterface* stream, + CompletionQueue* cq, void* tag) { + new AsyncRequest(this, context, stream, cq, tag); +} + void Server::ScheduleCallback() { { std::unique_lock lock(mu_); diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 5de592334d7..835596d393a 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -41,7 +41,8 @@ namespace grpc { -ServerBuilder::ServerBuilder() : thread_pool_(nullptr) {} +ServerBuilder::ServerBuilder() + : generic_service_(nullptr), thread_pool_(nullptr) {} void ServerBuilder::RegisterService(SynchronousService* service) { services_.push_back(service->service()); @@ -51,6 +52,16 @@ void ServerBuilder::RegisterAsyncService(AsynchronousService* service) { async_services_.push_back(service); } +void ServerBuilder::RegisterAsyncGenericService(AsyncGenericService* service) { + if (generic_service_) { + gpr_log(GPR_ERROR, + "Adding multiple AsyncGenericService is unsupported for now. " + "Dropping the service %p", service); + return; + } + generic_service_ = service; +} + void ServerBuilder::AddPort(const grpc::string& addr, std::shared_ptr creds, int* selected_port) { @@ -84,6 +95,9 @@ std::unique_ptr ServerBuilder::BuildAndStart() { return nullptr; } } + if (generic_service_) { + server->RegisterAsyncGenericService(generic_service_); + } for (auto& port : ports_) { int r = server->AddPort(port.addr, port.creds.get()); if (!r) return nullptr; diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc new file mode 100644 index 00000000000..f8d8eec0655 --- /dev/null +++ b/src/cpp/util/byte_buffer.cc @@ -0,0 +1,76 @@ +/* + * + * 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 + +namespace grpc { + +ByteBuffer::ByteBuffer(Slice* slices, size_t nslices) { + // TODO(yangg) maybe expose some core API to simplify this + std::vector c_slices(nslices); + for (size_t i = 0; i < nslices; i++) { + c_slices[i] = slices[i].slice_; + } + buffer_ = grpc_byte_buffer_create(c_slices.data(), nslices); +} + +void ByteBuffer::Clear() { + if (buffer_) { + grpc_byte_buffer_destroy(buffer_); + buffer_ = nullptr; + } +} + +void ByteBuffer::Dump(std::vector* slices) { + slices->clear(); + if (!buffer_) { + return; + } + grpc_byte_buffer_reader* reader = grpc_byte_buffer_reader_create(buffer_); + gpr_slice s; + while (grpc_byte_buffer_reader_next(reader, &s)) { + slices->push_back(Slice(s, Slice::STEAL_REF)); + gpr_slice_unref(s); + } + grpc_byte_buffer_reader_destroy(reader); +} + +size_t ByteBuffer::Length() { + if (buffer_) { + return grpc_byte_buffer_length(buffer_); + } else { + return 0; + } +} + +} // namespace grpc diff --git a/src/cpp/util/slice.cc b/src/cpp/util/slice.cc new file mode 100644 index 00000000000..a549c5008df --- /dev/null +++ b/src/cpp/util/slice.cc @@ -0,0 +1,50 @@ +/* + * + * 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 + +namespace grpc { + +Slice::Slice() : slice_(gpr_empty_slice()) {} + +Slice::~Slice() { + gpr_slice_unref(slice_); +} + +Slice::Slice(gpr_slice slice, AddRef) : slice_(gpr_slice_ref(slice)) {} + +Slice::Slice(gpr_slice slice, StealRef) : slice_(slice) {} + +Slice::Slice(const Slice& other) : slice_(gpr_slice_ref(other.slice_)) {} + +} // namespace grpc diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc new file mode 100644 index 00000000000..4a0d2c5c01d --- /dev/null +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -0,0 +1,271 @@ +/* + * + * 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 + +#include "src/cpp/proto/proto_utils.h" +#include "src/cpp/util/time.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/echo.pb.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using grpc::cpp::test::util::EchoRequest; +using grpc::cpp::test::util::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +void* tag(int i) { return (void*)(gpr_intptr)i; } + +void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { + bool ok; + void* got_tag; + EXPECT_TRUE(cq->Next(&got_tag, &ok)); + EXPECT_EQ(expect_ok, ok); + EXPECT_EQ(tag(i), got_tag); +} + +bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) { + std::vector slices; + buffer->Dump(&slices); + grpc::string buf; + buf.reserve(buffer->Length()); + for (const Slice& s : slices) { + buf.append(reinterpret_cast(s.begin()), s.size()); + } + return message->ParseFromString(buf); +} + +class GenericEnd2endTest : public ::testing::Test { + protected: + GenericEnd2endTest() : generic_service_("*") {} + + void SetUp() GRPC_OVERRIDE { + int port = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << port; + // Setup server + ServerBuilder builder; + builder.AddPort(server_address_.str(), InsecureServerCredentials()); + builder.RegisterAsyncGenericService(&generic_service_); + server_ = builder.BuildAndStart(); + } + + void TearDown() GRPC_OVERRIDE { + server_->Shutdown(); + void* ignored_tag; + bool ignored_ok; + cli_cq_.Shutdown(); + srv_cq_.Shutdown(); + while (cli_cq_.Next(&ignored_tag, &ignored_ok)) + ; + while (srv_cq_.Next(&ignored_tag, &ignored_ok)) + ; + } + + void ResetStub() { + std::shared_ptr channel = + CreateChannel(server_address_.str(), InsecureCredentials(), ChannelArguments()); + stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel)); + } + + void server_ok(int i) { verify_ok(&srv_cq_, i, true); } + void client_ok(int i) { verify_ok(&cli_cq_, i, true); } + void server_fail(int i) { verify_ok(&srv_cq_, i, false); } + void client_fail(int i) { verify_ok(&cli_cq_, i, false); } + + void SendRpc(int num_rpcs) { + for (int i = 0; i < num_rpcs; i++) { + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter stream(&srv_ctx); + + send_request.set_message("Hello"); + std::unique_ptr > response_reader( + stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1))); + client_ok(1); + + generic_service_.RequestCall(&srv_ctx, &stream, &srv_cq_, tag(2)); + + verify_ok(generic_service_.completion_queue(), 2, true); + EXPECT_EQ(server_address_.str(), srv_ctx.host()); + EXPECT_EQ("/grpc.cpp.test.util.TestService/Echo", srv_ctx.method()); + ByteBuffer recv_buffer; + stream.Read(&recv_buffer, tag(3)); + server_ok(3); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + grpc::string buf; + send_response.SerializeToString(&buf); + gpr_slice s = gpr_slice_from_copied_string(buf.c_str()); + Slice slice(s, Slice::STEAL_REF); + ByteBuffer send_buffer(&slice, 1); + stream.Write(send_buffer, tag(4)); + server_ok(4); + + stream.Finish(Status::OK, tag(5)); + server_ok(5); + + response_reader->Finish(&recv_response, &recv_status, tag(4)); + client_ok(4); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.IsOk()); + } + } + + CompletionQueue cli_cq_; + CompletionQueue srv_cq_; + std::unique_ptr stub_; + std::unique_ptr server_; + AsyncGenericService generic_service_; + std::ostringstream server_address_; +}; + +TEST_F(GenericEnd2endTest, SimpleRpc) { + ResetStub(); + SendRpc(1); +} + +TEST_F(GenericEnd2endTest, SequentialRpcs) { + ResetStub(); + SendRpc(10); +} + +// One ping, one pong. +TEST_F(GenericEnd2endTest, SimpleBidiStreaming) { + ResetStub(); + + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter srv_stream(&srv_ctx); + + send_request.set_message("Hello"); + std::unique_ptr > + cli_stream(stub_->AsyncBidiStream(&cli_ctx, &cli_cq_, tag(1))); + client_ok(1); + + generic_service_.RequestCall(&srv_ctx, &srv_stream, &srv_cq_, tag(2)); + + verify_ok(generic_service_.completion_queue(), 2, true); + EXPECT_EQ(server_address_.str(), srv_ctx.host()); + EXPECT_EQ("/grpc.cpp.test.util.TestService/BidiStream", srv_ctx.method()); + + cli_stream->Write(send_request, tag(3)); + client_ok(3); + + ByteBuffer recv_buffer; + srv_stream.Read(&recv_buffer, tag(4)); + server_ok(4); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + grpc::string buf; + send_response.SerializeToString(&buf); + gpr_slice s = gpr_slice_from_copied_string(buf.c_str()); + Slice slice(s, Slice::STEAL_REF); + ByteBuffer send_buffer(&slice, 1); + srv_stream.Write(send_buffer, tag(5)); + server_ok(5); + + cli_stream->Read(&recv_response, tag(6)); + client_ok(6); + EXPECT_EQ(send_response.message(), recv_response.message()); + + + cli_stream->WritesDone(tag(7)); + client_ok(7); + + recv_buffer.Clear(); + srv_stream.Read(&recv_buffer, tag(8)); + server_fail(8); + + srv_stream.Finish(Status::OK, tag(9)); + server_ok(9); + + cli_stream->Finish(&recv_status, tag(10)); + client_ok(10); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.IsOk()); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + grpc_shutdown(); + google::protobuf::ShutdownProtobufLibrary(); + return result; +} diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 6f354452aa5..355d5735cdc 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -356,6 +356,11 @@ "language": "c++", "name": "end2end_test" }, + { + "flaky": false, + "language": "c++", + "name": "generic_end2end_test" + }, { "flaky": false, "language": "c++",