aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile45
-rw-r--r--build.json16
-rw-r--r--include/grpc++/async_unary_call.h13
-rw-r--r--include/grpc++/stream.h98
-rw-r--r--src/compiler/cpp_generator.cc479
-rw-r--r--test/cpp/end2end/mock_test.cc291
-rw-r--r--tools/run_tests/tests.json9
7 files changed, 797 insertions, 154 deletions
diff --git a/Makefile b/Makefile
index fa6f9f537d..f90b97bc8b 100644
--- a/Makefile
+++ b/Makefile
@@ -680,6 +680,7 @@ grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
interop_client: $(BINDIR)/$(CONFIG)/interop_client
interop_server: $(BINDIR)/$(CONFIG)/interop_server
interop_test: $(BINDIR)/$(CONFIG)/interop_test
+mock_test: $(BINDIR)/$(CONFIG)/mock_test
pubsub_client: $(BINDIR)/$(CONFIG)/pubsub_client
pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test
pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test
@@ -1079,7 +1080,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)/dualstack_socket_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_tls_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)/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)/timers_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_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_registered_call_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_response_with_trailing_metadata_and_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_simple_request_with_high_initial_sequence_number_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_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_registered_call_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_response_with_trailing_metadata_and_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_simple_request_with_high_initial_sequence_number_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_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_registered_call_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_response_with_trailing_metadata_and_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_simple_request_with_high_initial_sequence_number_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_max_message_length_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_registered_call_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_response_with_trailing_metadata_and_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_simple_request_with_high_initial_sequence_number_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_max_message_length_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_registered_call_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_response_with_trailing_metadata_and_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_simple_request_with_high_initial_sequence_number_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_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_registered_call_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_response_with_trailing_metadata_and_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_simple_request_with_high_initial_sequence_number_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_max_message_length_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_registered_call_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_response_with_trailing_metadata_and_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_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_unsecure_test
-buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/credentials_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)/qps_smoke_test $(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)/cli_call_test $(BINDIR)/$(CONFIG)/credentials_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)/mock_test $(BINDIR)/$(CONFIG)/qps_smoke_test $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
test: test_c test_cxx
@@ -1829,6 +1830,8 @@ test_cxx: buildtests_cxx
$(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 mock_test"
+ $(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 )
$(E) "[RUN] Testing status_test"
$(Q) $(BINDIR)/$(CONFIG)/status_test || ( echo test status_test failed ; exit 1 )
$(E) "[RUN] Testing thread_pool_test"
@@ -7235,6 +7238,46 @@ endif
endif
+MOCK_TEST_SRC = \
+ test/cpp/end2end/mock_test.cc \
+
+MOCK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(MOCK_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/mock_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)/mock_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/mock_test: $(PROTOBUF_DEP) $(MOCK_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) $(MOCK_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 $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/mock_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/mock_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_mock_test: $(MOCK_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(MOCK_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
PUBSUB_CLIENT_SRC = \
examples/pubsub/main.cc \
diff --git a/build.json b/build.json
index e795d9af1a..7cf9231486 100644
--- a/build.json
+++ b/build.json
@@ -2000,6 +2000,22 @@
]
},
{
+ "name": "mock_test",
+ "build": "test",
+ "language": "c++",
+ "src": [
+ "test/cpp/end2end/mock_test.cc"
+ ],
+ "deps": [
+ "grpc++_test_util",
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr_test_util",
+ "gpr"
+ ]
+ },
+ {
"name": "pubsub_client",
"build": "do_not_build",
"run": false,
diff --git a/include/grpc++/async_unary_call.h b/include/grpc++/async_unary_call.h
index d1d5be5b50..97cec77955 100644
--- a/include/grpc++/async_unary_call.h
+++ b/include/grpc++/async_unary_call.h
@@ -44,8 +44,19 @@
#include <grpc/support/log.h>
namespace grpc {
+
+template <class R>
+class ClientAsyncResponseReaderInterface {
+ public:
+ virtual ~ClientAsyncResponseReaderInterface() {}
+ virtual void ReadInitialMetadata(void* tag) = 0;
+ virtual void Finish(R* msg, Status* status, void* tag) = 0;
+
+};
+
template <class R>
-class ClientAsyncResponseReader GRPC_FINAL {
+class ClientAsyncResponseReader GRPC_FINAL
+ : public ClientAsyncResponseReaderInterface<R> {
public:
ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
diff --git a/include/grpc++/stream.h b/include/grpc++/stream.h
index 6647e345c0..0efdbdaeca 100644
--- a/include/grpc++/stream.h
+++ b/include/grpc++/stream.h
@@ -83,8 +83,14 @@ class WriterInterface {
};
template <class R>
-class ClientReader GRPC_FINAL : public ClientStreamingInterface,
- public ReaderInterface<R> {
+class ClientReaderInterface : public ClientStreamingInterface,
+ public ReaderInterface<R> {
+ public:
+ virtual void WaitForInitialMetadata() = 0;
+};
+
+template <class R>
+class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
public:
// Blocking create a stream and write the first request out.
ClientReader(ChannelInterface* channel, const RpcMethod& method,
@@ -111,7 +117,7 @@ class ClientReader GRPC_FINAL : public ClientStreamingInterface,
GPR_ASSERT(cq_.Pluck(&buf));
}
- virtual bool Read(R* msg) GRPC_OVERRIDE {
+ bool Read(R* msg) GRPC_OVERRIDE {
CallOpBuffer buf;
if (!context_->initial_metadata_received_) {
buf.AddRecvInitialMetadata(context_);
@@ -121,7 +127,7 @@ class ClientReader GRPC_FINAL : public ClientStreamingInterface,
return cq_.Pluck(&buf) && buf.got_message;
}
- virtual Status Finish() GRPC_OVERRIDE {
+ Status Finish() GRPC_OVERRIDE {
CallOpBuffer buf;
Status status;
buf.AddClientRecvStatus(context_, &status);
@@ -137,8 +143,14 @@ class ClientReader GRPC_FINAL : public ClientStreamingInterface,
};
template <class W>
-class ClientWriter GRPC_FINAL : public ClientStreamingInterface,
- public WriterInterface<W> {
+class ClientWriterInterface : public ClientStreamingInterface,
+ public WriterInterface<W> {
+ public:
+ virtual bool WritesDone() = 0;
+};
+
+template <class W>
+class ClientWriter GRPC_FINAL : public ClientWriterInterface<W> {
public:
// Blocking create a stream.
ClientWriter(ChannelInterface* channel, const RpcMethod& method,
@@ -152,14 +164,14 @@ class ClientWriter GRPC_FINAL : public ClientStreamingInterface,
cq_.Pluck(&buf);
}
- virtual bool Write(const W& msg) GRPC_OVERRIDE {
+ bool Write(const W& msg) GRPC_OVERRIDE {
CallOpBuffer buf;
buf.AddSendMessage(msg);
call_.PerformOps(&buf);
return cq_.Pluck(&buf);
}
- virtual bool WritesDone() {
+ bool WritesDone() GRPC_OVERRIDE {
CallOpBuffer buf;
buf.AddClientSendClose();
call_.PerformOps(&buf);
@@ -167,7 +179,7 @@ class ClientWriter GRPC_FINAL : public ClientStreamingInterface,
}
// Read the final response and wait for the final status.
- virtual Status Finish() GRPC_OVERRIDE {
+ Status Finish() GRPC_OVERRIDE {
CallOpBuffer buf;
Status status;
buf.AddRecvMessage(response_);
@@ -186,9 +198,16 @@ class ClientWriter GRPC_FINAL : public ClientStreamingInterface,
// Client-side interface for bi-directional streaming.
template <class W, class R>
-class ClientReaderWriter GRPC_FINAL : public ClientStreamingInterface,
- public WriterInterface<W>,
- public ReaderInterface<R> {
+class ClientReaderWriterInterface : public ClientStreamingInterface,
+ public WriterInterface<W>,
+ public ReaderInterface<R> {
+ public:
+ virtual void WaitForInitialMetadata() = 0;
+ virtual bool WritesDone() = 0;
+};
+
+template <class W, class R>
+class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
public:
// Blocking create a stream.
ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
@@ -213,7 +232,7 @@ class ClientReaderWriter GRPC_FINAL : public ClientStreamingInterface,
GPR_ASSERT(cq_.Pluck(&buf));
}
- virtual bool Read(R* msg) GRPC_OVERRIDE {
+ bool Read(R* msg) GRPC_OVERRIDE {
CallOpBuffer buf;
if (!context_->initial_metadata_received_) {
buf.AddRecvInitialMetadata(context_);
@@ -223,21 +242,21 @@ class ClientReaderWriter GRPC_FINAL : public ClientStreamingInterface,
return cq_.Pluck(&buf) && buf.got_message;
}
- virtual bool Write(const W& msg) GRPC_OVERRIDE {
+ bool Write(const W& msg) GRPC_OVERRIDE {
CallOpBuffer buf;
buf.AddSendMessage(msg);
call_.PerformOps(&buf);
return cq_.Pluck(&buf);
}
- virtual bool WritesDone() {
+ bool WritesDone() GRPC_OVERRIDE {
CallOpBuffer buf;
buf.AddClientSendClose();
call_.PerformOps(&buf);
return cq_.Pluck(&buf);
}
- virtual Status Finish() GRPC_OVERRIDE {
+ Status Finish() GRPC_OVERRIDE {
CallOpBuffer buf;
Status status;
buf.AddClientRecvStatus(context_, &status);
@@ -267,7 +286,7 @@ class ServerReader GRPC_FINAL : public ReaderInterface<R> {
call_->cq()->Pluck(&buf);
}
- virtual bool Read(R* msg) GRPC_OVERRIDE {
+ bool Read(R* msg) GRPC_OVERRIDE {
CallOpBuffer buf;
buf.AddRecvMessage(msg);
call_->PerformOps(&buf);
@@ -294,7 +313,7 @@ class ServerWriter GRPC_FINAL : public WriterInterface<W> {
call_->cq()->Pluck(&buf);
}
- virtual bool Write(const W& msg) GRPC_OVERRIDE {
+ bool Write(const W& msg) GRPC_OVERRIDE {
CallOpBuffer buf;
if (!ctx_->sent_initial_metadata_) {
buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
@@ -327,14 +346,14 @@ class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
call_->cq()->Pluck(&buf);
}
- virtual bool Read(R* msg) GRPC_OVERRIDE {
+ bool Read(R* msg) GRPC_OVERRIDE {
CallOpBuffer buf;
buf.AddRecvMessage(msg);
call_->PerformOps(&buf);
return call_->cq()->Pluck(&buf) && buf.got_message;
}
- virtual bool Write(const W& msg) GRPC_OVERRIDE {
+ bool Write(const W& msg) GRPC_OVERRIDE {
CallOpBuffer buf;
if (!ctx_->sent_initial_metadata_) {
buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
@@ -380,8 +399,12 @@ class AsyncWriterInterface {
};
template <class R>
-class ClientAsyncReader GRPC_FINAL : public ClientAsyncStreamingInterface,
- public AsyncReaderInterface<R> {
+class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
+ public AsyncReaderInterface<R> {
+};
+
+template <class R>
+class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
public:
// Create a stream and write the first request out.
ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
@@ -431,8 +454,14 @@ class ClientAsyncReader GRPC_FINAL : public ClientAsyncStreamingInterface,
};
template <class W>
-class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface,
- public AsyncWriterInterface<W> {
+class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
+ public AsyncWriterInterface<W> {
+ public:
+ virtual void WritesDone(void* tag) = 0;
+};
+
+template <class W>
+class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
public:
ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
@@ -459,7 +488,7 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface,
call_.PerformOps(&write_buf_);
}
- void WritesDone(void* tag) {
+ void WritesDone(void* tag) GRPC_OVERRIDE {
writes_done_buf_.Reset(tag);
writes_done_buf_.AddClientSendClose();
call_.PerformOps(&writes_done_buf_);
@@ -488,9 +517,16 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface,
// Client-side interface for bi-directional streaming.
template <class W, class R>
-class ClientAsyncReaderWriter GRPC_FINAL : public ClientAsyncStreamingInterface,
- public AsyncWriterInterface<W>,
- public AsyncReaderInterface<R> {
+class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
+ public AsyncWriterInterface<W>,
+ public AsyncReaderInterface<R> {
+ public:
+ virtual void WritesDone(void* tag) = 0;
+};
+
+template <class W, class R>
+class ClientAsyncReaderWriter GRPC_FINAL
+ : public ClientAsyncReaderWriterInterface<W, R> {
public:
ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
const RpcMethod& method, ClientContext* context,
@@ -524,7 +560,7 @@ class ClientAsyncReaderWriter GRPC_FINAL : public ClientAsyncStreamingInterface,
call_.PerformOps(&write_buf_);
}
- void WritesDone(void* tag) {
+ void WritesDone(void* tag) GRPC_OVERRIDE {
writes_done_buf_.Reset(tag);
writes_done_buf_.AddClientSendClose();
call_.PerformOps(&writes_done_buf_);
@@ -671,13 +707,13 @@ class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
call_.PerformOps(&meta_buf_);
}
- virtual void Read(R* msg, void* tag) GRPC_OVERRIDE {
+ void Read(R* msg, void* tag) GRPC_OVERRIDE {
read_buf_.Reset(tag);
read_buf_.AddRecvMessage(msg);
call_.PerformOps(&read_buf_);
}
- virtual void Write(const W& msg, void* tag) GRPC_OVERRIDE {
+ void Write(const W& msg, void* tag) GRPC_OVERRIDE {
write_buf_.Reset(tag);
if (!ctx_->sent_initial_metadata_) {
write_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 735e7e58a8..a0c9d3d468 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -156,50 +156,16 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
"#include <grpc++/impl/internal_stub.h>\n"
"#include <grpc++/impl/rpc_method.h>\n"
"#include <grpc++/impl/service_type.h>\n"
+ "#include <grpc++/async_unary_call.h>\n"
"#include <grpc++/status.h>\n"
+ "#include <grpc++/stream.h>\n"
"\n"
"namespace grpc {\n"
"class CompletionQueue;\n"
"class ChannelInterface;\n"
"class RpcService;\n"
- "class ServerContext;\n";
- if (HasUnaryCalls(file)) {
- temp.append(
- "template <class OutMessage> class ClientAsyncResponseReader;\n");
- temp.append(
- "template <class OutMessage> class ServerAsyncResponseWriter;\n");
- }
- if (HasClientOnlyStreaming(file)) {
- temp.append("template <class OutMessage> class ClientWriter;\n");
- temp.append("template <class InMessage> class ServerReader;\n");
- temp.append("template <class OutMessage> class ClientAsyncWriter;\n");
- temp.append(
- "template <class OutMessage, class InMessage> class "
- "ServerAsyncReader;\n");
- }
- if (HasServerOnlyStreaming(file)) {
- temp.append("template <class InMessage> class ClientReader;\n");
- temp.append("template <class OutMessage> class ServerWriter;\n");
- temp.append("template <class OutMessage> class ClientAsyncReader;\n");
- temp.append("template <class InMessage> class ServerAsyncWriter;\n");
- }
- if (HasBidiStreaming(file)) {
- temp.append(
- "template <class OutMessage, class InMessage>\n"
- "class ClientReaderWriter;\n");
- temp.append(
- "template <class OutMessage, class InMessage>\n"
- "class ServerReaderWriter;\n");
- temp.append(
- "template <class OutMessage, class InMessage>\n"
- "class ClientAsyncReaderWriter;\n");
- temp.append(
- "template <class OutMessage, class InMessage>\n"
- "class ServerAsyncReaderWriter;\n");
- }
- temp.append("} // namespace grpc\n");
-
- temp.append("\n");
+ "class ServerContext;\n"
+ "} // namespace grpc\n\n";
if (!file->package().empty()) {
std::vector<grpc::string> parts =
@@ -216,54 +182,314 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
return temp;
}
+void PrintHeaderClientMethodInterfaces(grpc::protobuf::io::Printer *printer,
+ const grpc::protobuf::MethodDescriptor *method,
+ std::map<grpc::string, grpc::string> *vars,
+ bool is_public) {
+ (*vars)["Method"] = method->name();
+ (*vars)["Request"] =
+ grpc_cpp_generator::ClassName(method->input_type(), true);
+ (*vars)["Response"] =
+ grpc_cpp_generator::ClassName(method->output_type(), true);
+
+ if (is_public) {
+ if (NoStreaming(method)) {
+ printer->Print(
+ *vars,
+ "virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
+ "const $Request$& request, $Response$* response) = 0;\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< "
+ "::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
+ "Async$Method$(::grpc::ClientContext* context, "
+ "const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
+ "Async$Method$Raw(context, request, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else if (ClientOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
+ " $Method$("
+ "::grpc::ClientContext* context, $Response$* response) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< ::grpc::ClientWriterInterface< $Request$>>"
+ "($Method$Raw(context, response));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
+ " Async$Method$(::grpc::ClientContext* context, $Response$* response, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientAsyncWriterInterface< $Request$>>("
+ "Async$Method$Raw(context, response, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else if (ServerOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
+ " $Method$(::grpc::ClientContext* context, const $Request$& request)"
+ " {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< ::grpc::ClientReaderInterface< $Response$>>"
+ "($Method$Raw(context, request));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
+ "Async$Method$("
+ "::grpc::ClientContext* context, const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientAsyncReaderInterface< $Response$>>("
+ "Async$Method$Raw(context, request, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else if (BidiStreaming(method)) {
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientReaderWriterInterface< $Request$, $Response$>> "
+ "$Method$(::grpc::ClientContext* context) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientReaderWriterInterface< $Request$, $Response$>>("
+ "$Method$Raw(context));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< "
+ "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
+ "Async$Method$(::grpc::ClientContext* context, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
+ "Async$Method$Raw(context, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ } else {
+ if (NoStreaming(method)) {
+ printer->Print(
+ *vars,
+ "virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
+ "Async$Method$Raw(::grpc::ClientContext* context, "
+ "const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
+ } else if (ClientOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "virtual ::grpc::ClientWriterInterface< $Request$>*"
+ " $Method$Raw("
+ "::grpc::ClientContext* context, $Response$* response) = 0;\n");
+ printer->Print(
+ *vars,
+ "virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
+ " Async$Method$Raw(::grpc::ClientContext* context, "
+ "$Response$* response, "
+ "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
+ } else if (ServerOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
+ "::grpc::ClientContext* context, const $Request$& request) = 0;\n");
+ printer->Print(
+ *vars,
+ "virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
+ "Async$Method$Raw("
+ "::grpc::ClientContext* context, const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
+ } else if (BidiStreaming(method)) {
+ printer->Print(
+ *vars,
+ "virtual ::grpc::ClientReaderWriterInterface< $Request$, $Response$>* "
+ "$Method$Raw(::grpc::ClientContext* context) = 0;\n");
+ printer->Print(
+ *vars,
+ "virtual ::grpc::ClientAsyncReaderWriterInterface< "
+ "$Request$, $Response$>* "
+ "Async$Method$Raw(::grpc::ClientContext* context, "
+ "::grpc::CompletionQueue* cq, void* tag) = 0;\n");
+ }
+ }
+}
+
void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer,
const grpc::protobuf::MethodDescriptor *method,
- std::map<grpc::string, grpc::string> *vars) {
+ std::map<grpc::string, grpc::string> *vars,
+ bool is_public) {
(*vars)["Method"] = method->name();
(*vars)["Request"] =
grpc_cpp_generator::ClassName(method->input_type(), true);
(*vars)["Response"] =
grpc_cpp_generator::ClassName(method->output_type(), true);
- if (NoStreaming(method)) {
- printer->Print(*vars,
- "::grpc::Status $Method$(::grpc::ClientContext* context, "
- "const $Request$& request, $Response$* response);\n");
- printer->Print(
- *vars,
- "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
- "Async$Method$(::grpc::ClientContext* context, "
- "const $Request$& request, "
- "::grpc::CompletionQueue* cq, void* tag);\n");
- } else if (ClientOnlyStreaming(method)) {
- printer->Print(
- *vars,
- "std::unique_ptr< ::grpc::ClientWriter< $Request$>> $Method$("
- "::grpc::ClientContext* context, $Response$* response);\n");
- printer->Print(
- *vars,
- "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> Async$Method$("
- "::grpc::ClientContext* context, $Response$* response, "
- "::grpc::CompletionQueue* cq, void* tag);\n");
- } else if (ServerOnlyStreaming(method)) {
- printer->Print(
- *vars,
- "std::unique_ptr< ::grpc::ClientReader< $Response$>> $Method$("
- "::grpc::ClientContext* context, const $Request$& request);\n");
- printer->Print(*vars,
- "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
- "Async$Method$("
- "::grpc::ClientContext* context, const $Request$& request, "
- "::grpc::CompletionQueue* cq, void* tag);\n");
- } else if (BidiStreaming(method)) {
- printer->Print(
- *vars,
- "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>> "
- "$Method$(::grpc::ClientContext* context);\n");
- printer->Print(*vars,
- "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
- "$Request$, $Response$>> "
- "Async$Method$(::grpc::ClientContext* context, "
- "::grpc::CompletionQueue* cq, void* tag);\n");
+
+ if (is_public) {
+ if (NoStreaming(method)) {
+ printer->Print(
+ *vars,
+ "::grpc::Status $Method$(::grpc::ClientContext* context, "
+ "const $Request$& request, $Response$* response) GRPC_OVERRIDE;\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
+ "Async$Method$(::grpc::ClientContext* context, "
+ "const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientAsyncResponseReader< $Response$>>("
+ "Async$Method$Raw(context, request, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else if (ClientOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
+ " $Method$("
+ "::grpc::ClientContext* context, $Response$* response) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< ::grpc::ClientWriter< $Request$>>"
+ "($Method$Raw(context, response));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
+ " Async$Method$(::grpc::ClientContext* context, $Response$* response, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
+ "Async$Method$Raw(context, response, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else if (ServerOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientReader< $Response$>>"
+ " $Method$(::grpc::ClientContext* context, const $Request$& request)"
+ " {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< ::grpc::ClientReader< $Response$>>"
+ "($Method$Raw(context, request));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
+ "Async$Method$("
+ "::grpc::ClientContext* context, const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
+ "Async$Method$Raw(context, request, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ } else if (BidiStreaming(method)) {
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>>"
+ " $Method$(::grpc::ClientContext* context) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientReaderWriter< $Request$, $Response$>>("
+ "$Method$Raw(context));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Print(
+ *vars,
+ "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
+ "$Request$, $Response$>> "
+ "Async$Method$(::grpc::ClientContext* context, "
+ "::grpc::CompletionQueue* cq, void* tag) {\n");
+ printer->Indent();
+ printer->Print(
+ *vars,
+ "return std::unique_ptr< "
+ "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
+ "Async$Method$Raw(context, cq, tag));\n");
+ printer->Outdent();
+ printer->Print("}\n");
+ }
+ } else {
+ if (NoStreaming(method)) {
+ printer->Print(
+ *vars,
+ "::grpc::ClientAsyncResponseReader< $Response$>* "
+ "Async$Method$Raw(::grpc::ClientContext* context, "
+ "const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
+ } else if (ClientOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "::grpc::ClientWriter< $Request$>* $Method$Raw("
+ "::grpc::ClientContext* context, $Response$* response) "
+ "GRPC_OVERRIDE;\n");
+ printer->Print(
+ *vars,
+ "::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
+ "::grpc::ClientContext* context, $Response$* response, "
+ "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
+ } else if (ServerOnlyStreaming(method)) {
+ printer->Print(
+ *vars,
+ "::grpc::ClientReader< $Response$>* $Method$Raw("
+ "::grpc::ClientContext* context, const $Request$& request)"
+ " GRPC_OVERRIDE;\n");
+ printer->Print(
+ *vars,
+ "::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
+ "::grpc::ClientContext* context, const $Request$& request, "
+ "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
+ } else if (BidiStreaming(method)) {
+ printer->Print(
+ *vars,
+ "::grpc::ClientReaderWriter< $Request$, $Response$>* "
+ "$Method$Raw(::grpc::ClientContext* context) GRPC_OVERRIDE;\n");
+ printer->Print(
+ *vars,
+ "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+ "Async$Method$Raw(::grpc::ClientContext* context, "
+ "::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;\n");
+ }
}
}
@@ -357,18 +583,37 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
// Client side
printer->Print(
- "class Stub GRPC_FINAL : public ::grpc::InternalStub {\n"
+ "class StubInterface {\n"
" public:\n");
printer->Indent();
+ printer->Print("virtual ~StubInterface() {}\n");
+ for (int i = 0; i < service->method_count(); ++i) {
+ PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, true);
+ }
+ printer->Outdent();
+ printer->Print("private:\n");
+ printer->Indent();
+ for (int i = 0; i < service->method_count(); ++i) {
+ PrintHeaderClientMethodInterfaces(printer, service->method(i), vars, false);
+ }
+ printer->Outdent();
+ printer->Print("};\n");
+ printer->Print(
+ "class Stub GRPC_FINAL : public StubInterface,"
+ " public ::grpc::InternalStub {\n public:\n");
+ printer->Indent();
printer->Print(
"Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
for (int i = 0; i < service->method_count(); ++i) {
- PrintHeaderClientMethod(printer, service->method(i), vars);
+ PrintHeaderClientMethod(printer, service->method(i), vars, true);
}
printer->Outdent();
- printer->Print(" private:\n");
+ printer->Print("\n private:\n");
printer->Indent();
for (int i = 0; i < service->method_count(); ++i) {
+ PrintHeaderClientMethod(printer, service->method(i), vars, false);
+ }
+ for (int i = 0; i < service->method_count(); ++i) {
PrintHeaderClientMethodData(printer, service->method(i), vars);
}
printer->Outdent();
@@ -535,93 +780,85 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer,
"}\n\n");
printer->Print(
*vars,
- "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
- "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
+ "::grpc::ClientAsyncResponseReader< $Response$>* "
+ "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
"const $Request$& request, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
- " return std::unique_ptr< "
- "::grpc::ClientAsyncResponseReader< $Response$>>(new "
+ " return new "
"::grpc::ClientAsyncResponseReader< $Response$>("
"channel(), cq, "
"rpcmethod_$Method$_, "
- "context, request, tag));\n"
+ "context, request, tag);\n"
"}\n\n");
} else if (ClientOnlyStreaming(method)) {
printer->Print(*vars,
- "std::unique_ptr< ::grpc::ClientWriter< $Request$>> "
- "$ns$$Service$::Stub::$Method$("
+ "::grpc::ClientWriter< $Request$>* "
+ "$ns$$Service$::Stub::$Method$Raw("
"::grpc::ClientContext* context, $Response$* response) {\n");
printer->Print(*vars,
- " return std::unique_ptr< ::grpc::ClientWriter< "
- "$Request$>>(new ::grpc::ClientWriter< $Request$>("
- "channel(),"
+ " return new ::grpc::ClientWriter< $Request$>("
+ "channel(), "
"rpcmethod_$Method$_, "
- "context, response));\n"
+ "context, response);\n"
"}\n\n");
printer->Print(*vars,
- "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> "
- "$ns$$Service$::Stub::Async$Method$("
+ "::grpc::ClientAsyncWriter< $Request$>* "
+ "$ns$$Service$::Stub::Async$Method$Raw("
"::grpc::ClientContext* context, $Response$* response, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
- " return std::unique_ptr< ::grpc::ClientAsyncWriter< "
- "$Request$>>(new ::grpc::ClientAsyncWriter< $Request$>("
+ " return new ::grpc::ClientAsyncWriter< $Request$>("
"channel(), cq, "
"rpcmethod_$Method$_, "
- "context, response, tag));\n"
+ "context, response, tag);\n"
"}\n\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
- "std::unique_ptr< ::grpc::ClientReader< $Response$>> "
- "$ns$$Service$::Stub::$Method$("
+ "::grpc::ClientReader< $Response$>* "
+ "$ns$$Service$::Stub::$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request) {\n");
printer->Print(*vars,
- " return std::unique_ptr< ::grpc::ClientReader< "
- "$Response$>>(new ::grpc::ClientReader< $Response$>("
- "channel(),"
+ " return new ::grpc::ClientReader< $Response$>("
+ "channel(), "
"rpcmethod_$Method$_, "
- "context, request));\n"
+ "context, request);\n"
"}\n\n");
printer->Print(*vars,
- "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
- "$ns$$Service$::Stub::Async$Method$("
+ "::grpc::ClientAsyncReader< $Response$>* "
+ "$ns$$Service$::Stub::Async$Method$Raw("
"::grpc::ClientContext* context, const $Request$& request, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
- " return std::unique_ptr< ::grpc::ClientAsyncReader< "
- "$Response$>>(new ::grpc::ClientAsyncReader< $Response$>("
+ " return new ::grpc::ClientAsyncReader< $Response$>("
"channel(), cq, "
"rpcmethod_$Method$_, "
- "context, request, tag));\n"
+ "context, request, tag);\n"
"}\n\n");
} else if (BidiStreaming(method)) {
printer->Print(
*vars,
- "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>> "
- "$ns$$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n");
+ "::grpc::ClientReaderWriter< $Request$, $Response$>* "
+ "$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
printer->Print(*vars,
- " return std::unique_ptr< ::grpc::ClientReaderWriter< "
- "$Request$, $Response$>>(new ::grpc::ClientReaderWriter< "
+ " return new ::grpc::ClientReaderWriter< "
"$Request$, $Response$>("
- "channel(),"
+ "channel(), "
"rpcmethod_$Method$_, "
- "context));\n"
+ "context);\n"
"}\n\n");
printer->Print(
*vars,
- "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
- "$Request$, $Response$>> "
- "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
+ "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
+ "$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
"::grpc::CompletionQueue* cq, void* tag) {\n");
printer->Print(*vars,
- " return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
- "$Request$, $Response$>>(new "
+ " return new "
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
"channel(), cq, "
"rpcmethod_$Method$_, "
- "context, tag));\n"
+ "context, tag);\n"
"}\n\n");
}
}
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
new file mode 100644
index 0000000000..a4b2ee3ca5
--- /dev/null
+++ b/test/cpp/end2end/mock_test.cc
@@ -0,0 +1,291 @@
+/*
+ *
+ * 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 <thread>
+
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/util/echo_duplicate.grpc.pb.h"
+#include "test/cpp/util/echo.grpc.pb.h"
+#include "src/cpp/server/thread_pool.h"
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include <grpc++/status.h>
+#include <grpc++/stream.h>
+#include <grpc++/time.h>
+#include <gtest/gtest.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+
+using grpc::cpp::test::util::EchoRequest;
+using grpc::cpp::test::util::EchoResponse;
+using grpc::cpp::test::util::TestService;
+using std::chrono::system_clock;
+
+namespace grpc {
+namespace testing {
+
+namespace {
+template <class W, class R>
+class MockClientReaderWriter GRPC_FINAL
+ : public ClientReaderWriterInterface<W, R> {
+ public:
+ void WaitForInitialMetadata() {}
+ bool Read(R* msg) GRPC_OVERRIDE { return true; }
+ bool Write(const W& msg) GRPC_OVERRIDE { return true; }
+ bool WritesDone() GRPC_OVERRIDE { return true; }
+ Status Finish() GRPC_OVERRIDE { return Status::OK; }
+};
+template <>
+class MockClientReaderWriter<EchoRequest, EchoResponse> GRPC_FINAL
+ : public ClientReaderWriterInterface<EchoRequest, EchoResponse> {
+ public:
+ MockClientReaderWriter() : writes_done_(false) {}
+ void WaitForInitialMetadata() {}
+ bool Read(EchoResponse* msg) GRPC_OVERRIDE {
+ if (writes_done_) return false;
+ msg->set_message(last_message_);
+ return true;
+ }
+ bool Write(const EchoRequest& msg) GRPC_OVERRIDE {
+ gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
+ last_message_ = msg.message();
+ return true;
+ }
+ bool WritesDone() GRPC_OVERRIDE {
+ writes_done_ = true;
+ return true;
+ }
+ Status Finish() GRPC_OVERRIDE { return Status::OK; }
+
+ private:
+ bool writes_done_;
+ grpc::string last_message_;
+};
+
+// Mocked stub.
+class MockStub : public TestService::StubInterface {
+ public:
+ MockStub() {}
+ ~MockStub() {}
+ Status Echo(ClientContext* context, const EchoRequest& request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ response->set_message(request.message());
+ return Status::OK;
+ }
+ Status Unimplemented(ClientContext* context, const EchoRequest& request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ return Status::OK;
+ }
+
+ private:
+ ClientAsyncResponseReaderInterface<EchoResponse>* AsyncEchoRaw(
+ ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
+ void* tag) GRPC_OVERRIDE {
+ return nullptr;
+ }
+ ClientWriterInterface<EchoRequest>* RequestStreamRaw(
+ ClientContext* context, EchoResponse* response) GRPC_OVERRIDE {
+ return nullptr;
+ }
+ ClientAsyncWriterInterface<EchoRequest>* AsyncRequestStreamRaw(
+ ClientContext* context, EchoResponse* response, CompletionQueue* cq,
+ void* tag) GRPC_OVERRIDE {
+ return nullptr;
+ }
+ ClientReaderInterface<EchoResponse>* ResponseStreamRaw(
+ ClientContext* context, const EchoRequest& request) GRPC_OVERRIDE {
+ return nullptr;
+ }
+ ClientAsyncReaderInterface<EchoResponse>* AsyncResponseStreamRaw(
+ ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
+ void* tag) GRPC_OVERRIDE {
+ return nullptr;
+ }
+ ClientReaderWriterInterface<EchoRequest, EchoResponse>* BidiStreamRaw(
+ ClientContext* context) GRPC_OVERRIDE {
+ return new MockClientReaderWriter<EchoRequest, EchoResponse>();
+ }
+ ClientAsyncReaderWriterInterface<EchoRequest, EchoResponse>*
+ AsyncBidiStreamRaw(ClientContext* context, CompletionQueue* cq,
+ void* tag) GRPC_OVERRIDE {
+ return nullptr;
+ }
+ ClientAsyncResponseReaderInterface<EchoResponse>* AsyncUnimplementedRaw(
+ ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
+ void* tag) GRPC_OVERRIDE {
+ return nullptr;
+ }
+};
+
+class FakeClient {
+ public:
+ explicit FakeClient(TestService::StubInterface* stub) : stub_(stub) {}
+
+ void DoEcho() {
+ ClientContext context;
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("hello world");
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(request.message(), response.message());
+ EXPECT_TRUE(s.IsOk());
+ }
+
+ void DoBidiStream() {
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ grpc::string msg("hello");
+
+ std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
+ stream = stub_->BidiStream(&context);
+
+ request.set_message(msg + "0");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ request.set_message(msg + "1");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ request.set_message(msg + "2");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ stream->WritesDone();
+ EXPECT_FALSE(stream->Read(&response));
+
+ Status s = stream->Finish();
+ EXPECT_TRUE(s.IsOk());
+ }
+
+ void ResetStub(TestService::StubInterface* stub) { stub_ = stub; }
+
+ private:
+ TestService::StubInterface* stub_;
+};
+
+class TestServiceImpl : public TestService::Service {
+ public:
+ Status Echo(ServerContext* context, const EchoRequest* request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ response->set_message(request->message());
+ return Status::OK;
+ }
+
+ Status BidiStream(ServerContext* context,
+ ServerReaderWriter<EchoResponse, EchoRequest>* stream)
+ GRPC_OVERRIDE {
+ EchoRequest request;
+ EchoResponse response;
+ while (stream->Read(&request)) {
+ gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
+ response.set_message(request.message());
+ stream->Write(response);
+ }
+ return Status::OK;
+ }
+};
+
+class MockTest : public ::testing::Test {
+ protected:
+ MockTest() : thread_pool_(2) {}
+
+ void SetUp() GRPC_OVERRIDE {
+ int port = grpc_pick_unused_port_or_die();
+ server_address_ << "localhost:" << port;
+ // Setup server
+ ServerBuilder builder;
+ builder.AddListeningPort(server_address_.str(),
+ InsecureServerCredentials());
+ builder.RegisterService(&service_);
+ builder.SetThreadPool(&thread_pool_);
+ server_ = builder.BuildAndStart();
+ }
+
+ void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
+
+ void ResetStub() {
+ std::shared_ptr<ChannelInterface> channel = CreateChannel(
+ server_address_.str(), InsecureCredentials(), ChannelArguments());
+ stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
+ }
+
+ std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
+ std::unique_ptr<Server> server_;
+ std::ostringstream server_address_;
+ TestServiceImpl service_;
+ ThreadPool thread_pool_;
+};
+
+// Do one real rpc and one mocked one
+TEST_F(MockTest, SimpleRpc) {
+ ResetStub();
+ FakeClient client(stub_.get());
+ client.DoEcho();
+ MockStub stub;
+ client.ResetStub(&stub);
+ client.DoEcho();
+}
+
+TEST_F(MockTest, BidiStream) {
+ ResetStub();
+ FakeClient client(stub_.get());
+ client.DoBidiStream();
+ MockStub stub;
+ client.ResetStub(&stub);
+ client.DoBidiStream();
+}
+
+} // namespace
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 6a1b4a41b2..8c17c27189 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -669,6 +669,15 @@
{
"flaky": false,
"language": "c++",
+ "name": "mock_test",
+ "platforms": [
+ "windows",
+ "posix"
+ ]
+ },
+ {
+ "flaky": false,
+ "language": "c++",
"name": "status_test",
"platforms": [
"windows",