aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD4
-rw-r--r--Makefile51
-rw-r--r--build.json19
-rw-r--r--composer.json1
-rw-r--r--include/grpc++/config.h2
-rw-r--r--include/grpc++/credentials.h6
-rw-r--r--include/grpc++/dynamic_thread_pool.h (renamed from test/cpp/util/fake_credentials.h)50
-rw-r--r--include/grpc++/impl/sync_no_cxx11.h2
-rw-r--r--include/grpc/grpc_security.h12
-rw-r--r--src/compiler/csharp_generator.cc12
-rw-r--r--src/core/channel/client_channel.c2
-rw-r--r--src/core/channel/compress_filter.c2
-rw-r--r--src/core/iomgr/iomgr.c1
-rw-r--r--src/core/iomgr/tcp_posix.c4
-rw-r--r--src/core/iomgr/tcp_server_windows.c20
-rw-r--r--src/core/security/credentials.c23
-rw-r--r--src/core/security/credentials.h13
-rw-r--r--src/core/security/google_default_credentials.c5
-rw-r--r--src/core/surface/call.c3
-rw-r--r--src/core/surface/server.c15
-rw-r--r--src/core/transport/chttp2/frame_data.c2
-rw-r--r--src/core/transport/chttp2/internal.h21
-rw-r--r--src/core/transport/chttp2/parsing.c5
-rw-r--r--src/core/transport/chttp2/stream_lists.c68
-rw-r--r--src/core/transport/chttp2/writing.c94
-rw-r--r--src/core/transport/chttp2_transport.c17
-rw-r--r--src/core/transport/transport_op_string.c10
-rw-r--r--src/cpp/client/secure_credentials.cc8
-rw-r--r--src/cpp/server/create_default_thread_pool.cc4
-rw-r--r--src/cpp/server/dynamic_thread_pool.cc131
-rw-r--r--src/cpp/util/time.cc3
-rw-r--r--src/csharp/Grpc.Auth/GoogleCredential.cs21
-rw-r--r--src/csharp/Grpc.Auth/Grpc.Auth.csproj40
-rw-r--r--src/csharp/Grpc.Auth/Grpc.Auth.nuspec3
-rw-r--r--src/csharp/Grpc.Auth/app.config2
-rw-r--r--src/csharp/Grpc.Auth/packages.config12
-rw-r--r--src/csharp/Grpc.Core.Tests/ClientServerTest.cs88
-rw-r--r--src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj24
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs202
-rw-r--r--src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs79
-rw-r--r--src/csharp/Grpc.Core.Tests/ServerTest.cs2
-rw-r--r--src/csharp/Grpc.Core.Tests/TimeoutsTest.cs207
-rw-r--r--src/csharp/Grpc.Core.Tests/TimespecTest.cs101
-rw-r--r--src/csharp/Grpc.Core.Tests/packages.config1
-rw-r--r--src/csharp/Grpc.Core/Call.cs15
-rw-r--r--src/csharp/Grpc.Core/Calls.cs18
-rw-r--r--src/csharp/Grpc.Core/Channel.cs18
-rw-r--r--src/csharp/Grpc.Core/ClientBase.cs6
-rw-r--r--src/csharp/Grpc.Core/Credentials.cs75
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj9
-rw-r--r--src/csharp/Grpc.Core/GrpcEnvironment.cs33
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs21
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs13
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs28
-rw-r--r--src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs60
-rw-r--r--src/csharp/Grpc.Core/Internal/CallSafeHandle.cs21
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs16
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionRegistry.cs5
-rw-r--r--src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs18
-rw-r--r--src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs10
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs (renamed from src/csharp/Grpc.Core/Internal/GrpcLog.cs)37
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCallHandler.cs33
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs8
-rw-r--r--src/csharp/Grpc.Core/Internal/Timespec.cs183
-rw-r--r--src/csharp/Grpc.Core/KeyCertificatePair.cs84
-rw-r--r--src/csharp/Grpc.Core/Logging/ConsoleLogger.cs103
-rw-r--r--src/csharp/Grpc.Core/Logging/ILogger.cs57
-rw-r--r--src/csharp/Grpc.Core/Server.cs60
-rw-r--r--src/csharp/Grpc.Core/ServerCallContext.cs13
-rw-r--r--src/csharp/Grpc.Core/ServerCredentials.cs89
-rw-r--r--src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs10
-rw-r--r--src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj10
-rw-r--r--src/csharp/Grpc.Examples.MathClient/MathClient.cs2
-rw-r--r--src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj10
-rw-r--r--src/csharp/Grpc.Examples.MathServer/MathServer.cs2
-rw-r--r--src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs120
-rw-r--r--src/csharp/Grpc.Examples/MathGrpc.cs30
-rw-r--r--src/csharp/Grpc.Examples/MathServiceImpl.cs9
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs4
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs12
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj10
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Client/app.config2
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj10
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Server/app.config2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj77
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClient.cs254
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs26
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropServer.cs4
-rw-r--r--src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs97
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestCredentials.cs2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestGrpc.cs48
-rw-r--r--src/csharp/Grpc.IntegrationTesting/app.config2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/packages.config13
-rw-r--r--src/csharp/Grpc.sln100
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c28
-rw-r--r--src/node/README.md2
-rw-r--r--src/node/ext/call.cc22
-rw-r--r--src/node/ext/call.h1
-rw-r--r--src/node/ext/channel.cc11
-rw-r--r--src/node/ext/channel.h1
-rw-r--r--src/node/ext/credentials.cc7
-rw-r--r--src/node/ext/server.cc2
-rw-r--r--src/node/ext/server_credentials.cc8
-rw-r--r--src/node/ext/server_credentials.h1
-rw-r--r--src/node/ext/timeval.cc1
-rw-r--r--src/node/src/client.js16
-rw-r--r--src/node/src/server.js18
-rw-r--r--src/node/test/call_test.js10
-rw-r--r--src/node/test/channel_test.js6
-rw-r--r--src/node/test/end_to_end_test.js110
-rw-r--r--src/node/test/server_test.js10
-rw-r--r--src/node/test/surface_test.js40
-rw-r--r--src/php/composer.json2
-rw-r--r--src/php/ext/grpc/credentials.c11
-rw-r--r--src/php/ext/grpc/server_credentials.c13
-rwxr-xr-xsrc/php/lib/Grpc/BaseStub.php5
-rw-r--r--src/python/src/grpc/_adapter/_c/types.h4
-rw-r--r--src/python/src/grpc/_adapter/_c/types/client_credentials.c20
-rw-r--r--src/python/src/grpc/_adapter/_c/types/server_credentials.c10
-rw-r--r--src/python/src/grpc/_adapter/_c/utility.c1
-rw-r--r--src/python/src/grpc/_adapter/_c_test.py12
-rw-r--r--src/python/src/grpc/_cython/_cygrpc/credentials.pyx14
-rw-r--r--src/python/src/grpc/_cython/_cygrpc/grpc.pxd4
-rw-r--r--src/python/src/grpc/_cython/adapter_low.py8
-rw-r--r--src/python/src/grpc/_cython/cygrpc.pyx4
-rw-r--r--src/python/src/grpc/_cython/cygrpc_test.py14
-rw-r--r--src/ruby/ext/grpc/rb_grpc.c6
-rw-r--r--src/ruby/ext/grpc/rb_server.c13
-rw-r--r--test/core/security/credentials_test.c14
-rw-r--r--test/cpp/end2end/end2end_test.cc82
-rw-r--r--test/cpp/end2end/mock_test.cc4
-rw-r--r--test/cpp/end2end/thread_stress_test.cc4
-rw-r--r--test/cpp/interop/client_helper.cc3
-rw-r--r--test/cpp/qps/server_async.cc1
-rw-r--r--test/cpp/qps/server_sync.cc13
-rw-r--r--test/cpp/qps/timer.cc2
-rw-r--r--test/cpp/server/dynamic_thread_pool_test.cc (renamed from test/cpp/util/fake_credentials.cc)53
-rw-r--r--test/cpp/util/cli_call_test.cc4
-rw-r--r--test/cpp/util/messages.proto1
-rw-r--r--tools/doxygen/Doxyfile.c++1
-rw-r--r--tools/doxygen/Doxyfile.c++.internal2
-rwxr-xr-xtools/run_tests/run_csharp.sh5
-rw-r--r--tools/run_tests/sources_and_headers.json24
-rw-r--r--tools/run_tests/tests.json9
-rw-r--r--vsprojects/grpc++/grpc++.vcxproj3
-rw-r--r--vsprojects/grpc++/grpc++.vcxproj.filters6
-rw-r--r--vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj3
-rw-r--r--vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters6
149 files changed, 2776 insertions, 1184 deletions
diff --git a/BUILD b/BUILD
index cd90d7d015..eba3882a9d 100644
--- a/BUILD
+++ b/BUILD
@@ -667,6 +667,7 @@ cc_library(
"src/cpp/proto/proto_utils.cc",
"src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc",
+ "src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/fixed_size_thread_pool.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/server.cc",
@@ -692,6 +693,7 @@ cc_library(
"include/grpc++/config_protobuf.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/dynamic_thread_pool.h",
"include/grpc++/fixed_size_thread_pool.h",
"include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
@@ -752,6 +754,7 @@ cc_library(
"src/cpp/proto/proto_utils.cc",
"src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc",
+ "src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/fixed_size_thread_pool.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/server.cc",
@@ -777,6 +780,7 @@ cc_library(
"include/grpc++/config_protobuf.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/dynamic_thread_pool.h",
"include/grpc++/fixed_size_thread_pool.h",
"include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
diff --git a/Makefile b/Makefile
index 8c50572147..0a8b5cfaf0 100644
--- a/Makefile
+++ b/Makefile
@@ -851,6 +851,7 @@ credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
cxx_byte_buffer_test: $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test
cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test
+dynamic_thread_pool_test: $(BINDIR)/$(CONFIG)/dynamic_thread_pool_test
end2end_test: $(BINDIR)/$(CONFIG)/end2end_test
fixed_size_thread_pool_test: $(BINDIR)/$(CONFIG)/fixed_size_thread_pool_test
generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test
@@ -1595,7 +1596,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)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/fd_conservation_posix_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_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_stack_lockfree_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_auth_context_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test $(BINDIR)/$(CONFIG)/grpc_security_connector_test $(BINDIR)/$(CONFIG)/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)/multiple_server_queues_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)/timeout_encoding_test $(BINDIR)/$(CONFIG)/timers_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/uri_parser_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_channel_connectivity_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_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_flags_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_server_finishes_request_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_channel_connectivity_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_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_flags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_server_finishes_request_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_compression_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_channel_connectivity_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_flags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_channel_connectivity_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_flags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_flags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_flags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_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_channel_connectivity_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_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_flags_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_server_finishes_request_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_fullstack_with_poll_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_flags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_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_channel_connectivity_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_payload_and_call_creds_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_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_flags_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_server_finishes_request_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_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_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_flags_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_server_finishes_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_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_payload_and_call_creds_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_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_flags_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_server_finishes_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_socket_pair_with_grpc_trace_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_compressed_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_flags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_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_channel_connectivity_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_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_flags_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_server_finishes_request_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_compression_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_channel_connectivity_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_flags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_compression_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_channel_connectivity_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_flags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_channel_connectivity_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_flags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_with_poll_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_channel_connectivity_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_flags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_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_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_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_flags_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_server_finishes_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_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_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_flags_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_server_finishes_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 $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_compressed_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_flags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
-buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test $(BINDIR)/$(CONFIG)/auth_property_iterator_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/client_crash_test $(BINDIR)/$(CONFIG)/client_crash_test_server $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test $(BINDIR)/$(CONFIG)/cxx_slice_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/fixed_size_thread_pool_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_interarrival_test $(BINDIR)/$(CONFIG)/qps_openloop_test $(BINDIR)/$(CONFIG)/qps_test $(BINDIR)/$(CONFIG)/secure_auth_context_test $(BINDIR)/$(CONFIG)/server_crash_test $(BINDIR)/$(CONFIG)/server_crash_test_client $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/thread_stress_test
+buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test $(BINDIR)/$(CONFIG)/auth_property_iterator_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/client_crash_test $(BINDIR)/$(CONFIG)/client_crash_test_server $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test $(BINDIR)/$(CONFIG)/cxx_slice_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/dynamic_thread_pool_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/fixed_size_thread_pool_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_interarrival_test $(BINDIR)/$(CONFIG)/qps_openloop_test $(BINDIR)/$(CONFIG)/qps_test $(BINDIR)/$(CONFIG)/secure_auth_context_test $(BINDIR)/$(CONFIG)/server_crash_test $(BINDIR)/$(CONFIG)/server_crash_test_client $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/thread_stress_test
test: test_c test_cxx
@@ -2992,6 +2993,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/cxx_slice_test || ( echo test cxx_slice_test failed ; exit 1 )
$(E) "[RUN] Testing cxx_time_test"
$(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 )
+ $(E) "[RUN] Testing dynamic_thread_pool_test"
+ $(Q) $(BINDIR)/$(CONFIG)/dynamic_thread_pool_test || ( echo test dynamic_thread_pool_test failed ; exit 1 )
$(E) "[RUN] Testing end2end_test"
$(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 )
$(E) "[RUN] Testing fixed_size_thread_pool_test"
@@ -4134,6 +4137,7 @@ LIBGRPC++_SRC = \
src/cpp/proto/proto_utils.cc \
src/cpp/server/async_generic_service.cc \
src/cpp/server/create_default_thread_pool.cc \
+ src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/fixed_size_thread_pool.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/server.cc \
@@ -4159,6 +4163,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/config_protobuf.h \
include/grpc++/create_channel.h \
include/grpc++/credentials.h \
+ include/grpc++/dynamic_thread_pool.h \
include/grpc++/fixed_size_thread_pool.h \
include/grpc++/generic_stub.h \
include/grpc++/impl/call.h \
@@ -4310,7 +4315,6 @@ LIBGRPC++_TEST_UTIL_SRC = \
$(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc \
test/cpp/util/cli_call.cc \
test/cpp/util/create_test_channel.cc \
- test/cpp/util/fake_credentials.cc \
test/cpp/util/subprocess.cc \
@@ -4357,7 +4361,6 @@ endif
endif
$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/fake_credentials.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/messages.grpc.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo.grpc.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc
@@ -4377,6 +4380,7 @@ LIBGRPC++_UNSECURE_SRC = \
src/cpp/proto/proto_utils.cc \
src/cpp/server/async_generic_service.cc \
src/cpp/server/create_default_thread_pool.cc \
+ src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/fixed_size_thread_pool.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/server.cc \
@@ -4402,6 +4406,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/config_protobuf.h \
include/grpc++/create_channel.h \
include/grpc++/credentials.h \
+ include/grpc++/dynamic_thread_pool.h \
include/grpc++/fixed_size_thread_pool.h \
include/grpc++/generic_stub.h \
include/grpc++/impl/call.h \
@@ -8686,6 +8691,46 @@ endif
endif
+DYNAMIC_THREAD_POOL_TEST_SRC = \
+ test/cpp/server/dynamic_thread_pool_test.cc \
+
+DYNAMIC_THREAD_POOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(DYNAMIC_THREAD_POOL_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/dynamic_thread_pool_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)/dynamic_thread_pool_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/dynamic_thread_pool_test: $(PROTOBUF_DEP) $(DYNAMIC_THREAD_POOL_TEST_OBJS) $(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) $(DYNAMIC_THREAD_POOL_TEST_OBJS) $(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)/dynamic_thread_pool_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/server/dynamic_thread_pool_test.o: $(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_dynamic_thread_pool_test: $(DYNAMIC_THREAD_POOL_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(DYNAMIC_THREAD_POOL_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
END2END_TEST_SRC = \
test/cpp/end2end/end2end_test.cc \
diff --git a/build.json b/build.json
index 37f2e32c42..943c5f2798 100644
--- a/build.json
+++ b/build.json
@@ -43,6 +43,7 @@
"include/grpc++/config_protobuf.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/dynamic_thread_pool.h",
"include/grpc++/fixed_size_thread_pool.h",
"include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
@@ -90,6 +91,7 @@
"src/cpp/proto/proto_utils.cc",
"src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc",
+ "src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/fixed_size_thread_pool.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/server.cc",
@@ -612,7 +614,6 @@
"headers": [
"test/cpp/util/cli_call.h",
"test/cpp/util/create_test_channel.h",
- "test/cpp/util/fake_credentials.h",
"test/cpp/util/subprocess.h"
],
"src": [
@@ -621,7 +622,6 @@
"test/cpp/util/echo_duplicate.proto",
"test/cpp/util/cli_call.cc",
"test/cpp/util/create_test_channel.cc",
- "test/cpp/util/fake_credentials.cc",
"test/cpp/util/subprocess.cc"
],
"deps": [
@@ -2048,6 +2048,21 @@
]
},
{
+ "name": "dynamic_thread_pool_test",
+ "build": "test",
+ "language": "c++",
+ "src": [
+ "test/cpp/server/dynamic_thread_pool_test.cc"
+ ],
+ "deps": [
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr_test_util",
+ "gpr"
+ ]
+ },
+ {
"name": "end2end_test",
"build": "test",
"language": "c++",
diff --git a/composer.json b/composer.json
index 875ec55d8a..1d78a2ce21 100644
--- a/composer.json
+++ b/composer.json
@@ -2,6 +2,7 @@
"name": "grpc/grpc",
"type": "library",
"description": "gRPC library for PHP",
+ "version": "0.5.1",
"keywords": ["rpc"],
"homepage": "http://grpc.io",
"license": "BSD-3-Clause",
diff --git a/include/grpc++/config.h b/include/grpc++/config.h
index 1362c0a1fa..889dc39eb7 100644
--- a/include/grpc++/config.h
+++ b/include/grpc++/config.h
@@ -79,6 +79,7 @@
#ifdef GRPC_CXX0X_NO_NULLPTR
#include <memory>
+namespace grpc {
const class {
public:
template <class T>
@@ -98,6 +99,7 @@ const class {
private:
void operator&() const = delete;
} nullptr = {};
+}
#endif
#ifndef GRPC_CUSTOM_STRING
diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h
index 0eaaefcbca..a4f1e73118 100644
--- a/include/grpc++/credentials.h
+++ b/include/grpc++/credentials.h
@@ -106,13 +106,13 @@ std::shared_ptr<Credentials> ServiceAccountCredentials(
const grpc::string& json_key, const grpc::string& scope,
long token_lifetime_seconds);
-// Builds JWT credentials.
+// Builds Service Account JWT Access credentials.
// json_key is the JSON key string containing the client's private key.
// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
// (JWT) created with this credentials. It should not exceed
// grpc_max_auth_token_lifetime or will be cropped to this value.
-std::shared_ptr<Credentials> JWTCredentials(const grpc::string& json_key,
- long token_lifetime_seconds);
+std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
+ const grpc::string& json_key, long token_lifetime_seconds);
// Builds refresh token credentials.
// json_refresh_token is the JSON string containing the refresh token along
diff --git a/test/cpp/util/fake_credentials.h b/include/grpc++/dynamic_thread_pool.h
index e1ba7bb9e4..bc4e2d4d74 100644
--- a/test/cpp/util/fake_credentials.h
+++ b/include/grpc++/dynamic_thread_pool.h
@@ -31,21 +31,51 @@
*
*/
-#ifndef GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
-#define GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
+#ifndef GRPCXX_DYNAMIC_THREAD_POOL_H
+#define GRPCXX_DYNAMIC_THREAD_POOL_H
-#include <memory>
+#include <grpc++/config.h>
+
+#include <grpc++/impl/sync.h>
+#include <grpc++/impl/thd.h>
+#include <grpc++/thread_pool_interface.h>
+
+#include <list>
+#include <queue>
namespace grpc {
-class Credentials;
-class ServerCredentials;
-namespace testing {
+class DynamicThreadPool GRPC_FINAL : public ThreadPoolInterface {
+ public:
+ explicit DynamicThreadPool(int reserve_threads);
+ ~DynamicThreadPool();
+
+ void Add(const std::function<void()>& callback) GRPC_OVERRIDE;
+
+ private:
+ class DynamicThread {
+ public:
+ DynamicThread(DynamicThreadPool *pool);
+ ~DynamicThread();
+ private:
+ DynamicThreadPool *pool_;
+ std::unique_ptr<grpc::thread> thd_;
+ void ThreadFunc();
+ };
+ grpc::mutex mu_;
+ grpc::condition_variable cv_;
+ grpc::condition_variable shutdown_cv_;
+ bool shutdown_;
+ std::queue<std::function<void()>> callbacks_;
+ int reserve_threads_;
+ int nthreads_;
+ int threads_waiting_;
+ std::list<DynamicThread*> dead_threads_;
-std::shared_ptr<Credentials> FakeTransportSecurityCredentials();
-std::shared_ptr<ServerCredentials> FakeTransportSecurityServerCredentials();
+ void ThreadFunc();
+ static void ReapThreads(std::list<DynamicThread*>* tlist);
+};
-} // namespace testing
} // namespace grpc
-#endif // GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
+#endif // GRPCXX_DYNAMIC_THREAD_POOL_H
diff --git a/include/grpc++/impl/sync_no_cxx11.h b/include/grpc++/impl/sync_no_cxx11.h
index dda939bf71..fda668957e 100644
--- a/include/grpc++/impl/sync_no_cxx11.h
+++ b/include/grpc++/impl/sync_no_cxx11.h
@@ -87,7 +87,7 @@ class condition_variable {
~condition_variable() { gpr_cv_destroy(&cv_); }
void wait(lock_guard<mutex> &mu) {
mu.locked = false;
- gpr_cv_wait(&cv_, &mu.mu_.mu_, gpr_inf_future);
+ gpr_cv_wait(&cv_, &mu.mu_.mu_, gpr_inf_future(GPR_CLOCK_REALTIME);
mu.locked = true;
}
void notify_one() { gpr_cv_signal(&cv_); }
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 37d66c04ae..29eddc57a8 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -119,8 +119,8 @@ grpc_credentials *grpc_service_account_credentials_create(
- token_lifetime is the lifetime of each Json Web Token (JWT) created with
this credentials. It should not exceed grpc_max_auth_token_lifetime or
will be cropped to this value. */
-grpc_credentials *grpc_jwt_credentials_create(const char *json_key,
- gpr_timespec token_lifetime);
+grpc_credentials *grpc_service_account_jwt_access_credentials_create(
+ const char *json_key, gpr_timespec token_lifetime);
/* Creates an Oauth2 Refresh Token credentials object. May return NULL if the
input is invalid.
@@ -140,9 +140,6 @@ grpc_credentials *grpc_access_token_credentials_create(
grpc_credentials *grpc_iam_credentials_create(const char *authorization_token,
const char *authority_selector);
-/* Creates a fake transport security credentials object for testing. */
-grpc_credentials *grpc_fake_transport_security_credentials_create(void);
-
/* --- Secure channel creation. --- */
/* The caller of the secure_channel_create functions may override the target
@@ -182,10 +179,6 @@ grpc_server_credentials *grpc_ssl_server_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs);
-/* Creates a fake server transport security credentials object for testing. */
-grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
- void);
-
/* --- Server-side secure ports. --- */
/* Add a HTTP2 over an encrypted link over tcp listener.
@@ -206,7 +199,6 @@ grpc_call_error grpc_call_set_credentials(grpc_call *call,
/* TODO(jboeuf): Define some well-known property names. */
#define GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME "transport_security_type"
-#define GRPC_FAKE_TRANSPORT_SECURITY_TYPE "fake"
#define GRPC_SSL_TRANSPORT_SECURITY_TYPE "ssl"
#define GRPC_X509_CN_PROPERTY_NAME "x509_common_name"
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index c80bd933ae..e0c1bcda19 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -269,7 +269,7 @@ void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
if (method_type == METHODTYPE_NO_STREAMING) {
// unary calls have an extra synchronous stub method
out->Print(
- "$response$ $methodname$($request$ request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));\n",
+ "$response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));\n",
"methodname", method->name(), "request",
GetClassName(method->input_type()), "response",
GetClassName(method->output_type()));
@@ -280,7 +280,7 @@ void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
method_name += "Async"; // prevent name clash with synchronous method.
}
out->Print(
- "$returntype$ $methodname$($request_maybe$Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));\n",
+ "$returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));\n",
"methodname", method_name, "request_maybe",
GetMethodRequestParamMaybe(method), "returntype",
GetMethodReturnTypeClient(method));
@@ -334,13 +334,13 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
if (method_type == METHODTYPE_NO_STREAMING) {
// unary calls have an extra synchronous stub method
out->Print(
- "public $response$ $methodname$($request$ request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))\n",
+ "public $response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
"methodname", method->name(), "request",
GetClassName(method->input_type()), "response",
GetClassName(method->output_type()));
out->Print("{\n");
out->Indent();
- out->Print("var call = CreateCall($servicenamefield$, $methodfield$, headers);\n",
+ out->Print("var call = CreateCall($servicenamefield$, $methodfield$, headers, deadline);\n",
"servicenamefield", GetServiceNameFieldName(), "methodfield",
GetMethodFieldName(method));
out->Print("return Calls.BlockingUnaryCall(call, request, cancellationToken);\n");
@@ -353,13 +353,13 @@ void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
method_name += "Async"; // prevent name clash with synchronous method.
}
out->Print(
- "public $returntype$ $methodname$($request_maybe$Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))\n",
+ "public $returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))\n",
"methodname", method_name, "request_maybe",
GetMethodRequestParamMaybe(method), "returntype",
GetMethodReturnTypeClient(method));
out->Print("{\n");
out->Indent();
- out->Print("var call = CreateCall($servicenamefield$, $methodfield$, headers);\n",
+ out->Print("var call = CreateCall($servicenamefield$, $methodfield$, headers, deadline);\n",
"servicenamefield", GetServiceNameFieldName(), "methodfield",
GetMethodFieldName(method));
switch (GetMethodType(method)) {
diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c
index 2457529c16..2cfca399b6 100644
--- a/src/core/channel/client_channel.c
+++ b/src/core/channel/client_channel.c
@@ -523,7 +523,7 @@ static void cc_on_config_changed(void *arg, int iomgr_success) {
while (wakeup_closures) {
grpc_iomgr_closure *next = wakeup_closures->next;
- grpc_iomgr_add_callback(wakeup_closures);
+ wakeup_closures->cb(wakeup_closures->cb_arg, 1);
wakeup_closures = next;
}
diff --git a/src/core/channel/compress_filter.c b/src/core/channel/compress_filter.c
index 14e8ca7325..4bf24e7db3 100644
--- a/src/core/channel/compress_filter.c
+++ b/src/core/channel/compress_filter.c
@@ -174,6 +174,8 @@ static void process_send_ops(grpc_call_element *elem,
size_t i;
int did_compress = 0;
+ /* In streaming calls, we need to reset the previously accumulated slices */
+ gpr_slice_buffer_reset_and_unref(&calld->slices);
for (i = 0; i < send_ops->nops; ++i) {
grpc_stream_op *sop = &send_ops->ops[i];
switch (sop->type) {
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 97b4ce5765..fdc9adf4af 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -88,6 +88,7 @@ void grpc_kick_poller(void) {
void grpc_iomgr_init(void) {
gpr_thd_id id;
+ g_shutdown = 0;
gpr_mu_init(&g_mu);
gpr_cv_init(&g_rcv);
grpc_alarm_list_init(gpr_now(GPR_CLOCK_MONOTONIC));
diff --git a/src/core/iomgr/tcp_posix.c b/src/core/iomgr/tcp_posix.c
index 29aa5e9601..24fee0596f 100644
--- a/src/core/iomgr/tcp_posix.c
+++ b/src/core/iomgr/tcp_posix.c
@@ -319,7 +319,7 @@ static void call_read_cb(grpc_tcp *tcp, gpr_slice *slices, size_t nslices,
gpr_log(GPR_DEBUG, "read: status=%d", status);
for (i = 0; i < nslices; i++) {
char *dump = gpr_dump_slice(slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII);
- gpr_log(GPR_DEBUG, "READ: %s", dump);
+ gpr_log(GPR_DEBUG, "READ %p: %s", tcp, dump);
gpr_free(dump);
}
}
@@ -448,7 +448,7 @@ static void grpc_tcp_notify_on_read(grpc_endpoint *ep, grpc_endpoint_read_cb cb,
grpc_fd_notify_on_read(tcp->em_fd, &tcp->read_closure);
} else {
tcp->handle_read_closure.cb_arg = tcp;
- grpc_iomgr_add_callback(&tcp->handle_read_closure);
+ grpc_iomgr_add_delayed_callback(&tcp->handle_read_closure, 1);
}
}
diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c
index e224de8534..cc680507ff 100644
--- a/src/core/iomgr/tcp_server_windows.c
+++ b/src/core/iomgr/tcp_server_windows.c
@@ -250,6 +250,7 @@ static void on_accept(void *arg, int from_iocp) {
DWORD transfered_bytes;
DWORD flags;
BOOL wsa_success;
+ int err;
/* The general mechanism for shutting down is to queue abortion calls. While
this is necessary in the read/write case, it's useless for the accept
@@ -281,8 +282,23 @@ static void on_accept(void *arg, int from_iocp) {
}
} else {
if (!sp->shutting_down) {
- getpeername(sock, (struct sockaddr *)&peer_name, &peer_name_len);
- peer_name_string = grpc_sockaddr_to_uri((struct sockaddr *)&peer_name);
+ peer_name_string = NULL;
+ err = setsockopt(sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
+ (char *)&sp->socket->socket,
+ sizeof(sp->socket->socket));
+ if (err) {
+ char *utf8_message = gpr_format_message(WSAGetLastError());
+ gpr_log(GPR_ERROR, "setsockopt error: %s", utf8_message);
+ gpr_free(utf8_message);
+ }
+ err = getpeername(sock, (struct sockaddr*)&peer_name, &peer_name_len);
+ if (!err) {
+ peer_name_string = grpc_sockaddr_to_uri((struct sockaddr*)&peer_name);
+ } else {
+ char *utf8_message = gpr_format_message(WSAGetLastError());
+ gpr_log(GPR_ERROR, "getpeername error: %s", utf8_message);
+ gpr_free(utf8_message);
+ }
gpr_asprintf(&fd_name, "tcp_server:%s", peer_name_string);
ep = grpc_tcp_create(grpc_winsocket_create(sock, fd_name),
peer_name_string);
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index fb59fa4b0e..38612cf308 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -315,7 +315,7 @@ grpc_server_credentials *grpc_ssl_server_credentials_create(
/* -- Jwt credentials -- */
-static void jwt_reset_cache(grpc_jwt_credentials *c) {
+static void jwt_reset_cache(grpc_service_account_jwt_access_credentials *c) {
if (c->cached.jwt_md != NULL) {
grpc_credentials_md_store_unref(c->cached.jwt_md);
c->cached.jwt_md = NULL;
@@ -328,7 +328,8 @@ static void jwt_reset_cache(grpc_jwt_credentials *c) {
}
static void jwt_destroy(grpc_credentials *creds) {
- grpc_jwt_credentials *c = (grpc_jwt_credentials *)creds;
+ grpc_service_account_jwt_access_credentials *c =
+ (grpc_service_account_jwt_access_credentials *)creds;
grpc_auth_json_key_destruct(&c->key);
jwt_reset_cache(c);
gpr_mu_destroy(&c->cache_mu);
@@ -346,7 +347,8 @@ static void jwt_get_request_metadata(grpc_credentials *creds,
const char *service_url,
grpc_credentials_metadata_cb cb,
void *user_data) {
- grpc_jwt_credentials *c = (grpc_jwt_credentials *)creds;
+ grpc_service_account_jwt_access_credentials *c =
+ (grpc_service_account_jwt_access_credentials *)creds;
gpr_timespec refresh_threshold = gpr_time_from_seconds(
GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
@@ -399,15 +401,16 @@ static grpc_credentials_vtable jwt_vtable = {
jwt_destroy, jwt_has_request_metadata, jwt_has_request_metadata_only,
jwt_get_request_metadata, NULL};
-grpc_credentials *grpc_jwt_credentials_create_from_auth_json_key(
+grpc_credentials *
+grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key key, gpr_timespec token_lifetime) {
- grpc_jwt_credentials *c;
+ grpc_service_account_jwt_access_credentials *c;
if (!grpc_auth_json_key_is_valid(&key)) {
gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
return NULL;
}
- c = gpr_malloc(sizeof(grpc_jwt_credentials));
- memset(c, 0, sizeof(grpc_jwt_credentials));
+ c = gpr_malloc(sizeof(grpc_service_account_jwt_access_credentials));
+ memset(c, 0, sizeof(grpc_service_account_jwt_access_credentials));
c->base.type = GRPC_CREDENTIALS_TYPE_JWT;
gpr_ref_init(&c->base.refcount, 1);
c->base.vtable = &jwt_vtable;
@@ -418,9 +421,9 @@ grpc_credentials *grpc_jwt_credentials_create_from_auth_json_key(
return &c->base;
}
-grpc_credentials *grpc_jwt_credentials_create(const char *json_key,
- gpr_timespec token_lifetime) {
- return grpc_jwt_credentials_create_from_auth_json_key(
+grpc_credentials *grpc_service_account_jwt_access_credentials_create(
+ const char *json_key, gpr_timespec token_lifetime) {
+ return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key_create_from_string(json_key), token_lifetime);
}
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index d988901cf7..8d40da47c1 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -52,6 +52,8 @@ typedef enum {
GRPC_CREDENTIALS_ERROR
} grpc_credentials_status;
+#define GRPC_FAKE_TRANSPORT_SECURITY_TYPE "fake"
+
#define GRPC_CREDENTIALS_TYPE_SSL "Ssl"
#define GRPC_CREDENTIALS_TYPE_OAUTH2 "Oauth2"
#define GRPC_CREDENTIALS_TYPE_JWT "Jwt"
@@ -112,6 +114,12 @@ void grpc_credentials_md_store_unref(grpc_credentials_md_store *store);
/* --- grpc_credentials. --- */
+/* Creates a fake transport security credentials object for testing. */
+grpc_credentials *grpc_fake_transport_security_credentials_create(void);
+/* Creates a fake server transport security credentials object for testing. */
+grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
+ void);
+
/* It is the caller's responsibility to gpr_free the result if not NULL. */
char *grpc_get_well_known_google_credentials_file_path(void);
@@ -188,7 +196,8 @@ grpc_credentials *grpc_fake_oauth2_credentials_create(
/* Private constructor for jwt credentials from an already parsed json key.
Takes ownership of the key. */
-grpc_credentials *grpc_jwt_credentials_create_from_auth_json_key(
+grpc_credentials *
+grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key key, gpr_timespec token_lifetime);
/* Private constructor for refresh token credentials from an already parsed
@@ -240,7 +249,7 @@ typedef struct {
grpc_auth_json_key key;
gpr_timespec jwt_lifetime;
-} grpc_jwt_credentials;
+} grpc_service_account_jwt_access_credentials;
/* -- Oauth2TokenFetcher credentials --
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index 833484310f..de1929fe76 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -140,8 +140,9 @@ static grpc_credentials *create_default_creds_from_path(char *creds_path) {
/* First, try an auth json key. */
key = grpc_auth_json_key_create_from_json(json);
if (grpc_auth_json_key_is_valid(&key)) {
- result = grpc_jwt_credentials_create_from_auth_json_key(
- key, grpc_max_auth_token_lifetime);
+ result =
+ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
+ key, grpc_max_auth_token_lifetime);
goto end;
}
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index aefcbad244..a1da822113 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1373,7 +1373,8 @@ static void recv_metadata(grpc_call *call, grpc_metadata_batch *md) {
l->md = 0;
}
}
- if (gpr_time_cmp(md->deadline, gpr_inf_future(GPR_CLOCK_REALTIME)) != 0) {
+ if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) !=
+ 0) {
set_deadline_alarm(call, md->deadline);
}
if (!is_trailing) {
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 24f35298ef..7b3e412db0 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -400,6 +400,15 @@ static void finish_start_new_rpc(grpc_server *server, grpc_call_element *elem,
call_data *calld = elem->call_data;
int request_id;
+ if (gpr_atm_acq_load(&server->shutdown_flag)) {
+ gpr_mu_lock(&calld->mu_state);
+ calld->state = ZOMBIED;
+ gpr_mu_unlock(&calld->mu_state);
+ grpc_iomgr_closure_init(&calld->kill_zombie_closure, kill_zombie, elem);
+ grpc_iomgr_add_callback(&calld->kill_zombie_closure);
+ return;
+ }
+
request_id = gpr_stack_lockfree_pop(request_matcher->requests);
if (request_id == -1) {
gpr_mu_lock(&server->mu_call);
@@ -530,6 +539,7 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) {
static void server_on_recv(void *ptr, int success) {
grpc_call_element *elem = ptr;
call_data *calld = elem->call_data;
+ gpr_timespec op_deadline;
if (success && !calld->got_initial_metadata) {
size_t i;
@@ -539,8 +549,9 @@ static void server_on_recv(void *ptr, int success) {
grpc_stream_op *op = &ops[i];
if (op->type != GRPC_OP_METADATA) continue;
grpc_metadata_batch_filter(&op->data.metadata, server_filter, elem);
- if (0 != gpr_time_cmp(op->data.metadata.deadline,
- gpr_inf_future(GPR_CLOCK_REALTIME))) {
+ op_deadline = op->data.metadata.deadline;
+ if (0 !=
+ gpr_time_cmp(op_deadline, gpr_inf_future(op_deadline.clock_type))) {
calld->deadline = op->data.metadata.deadline;
}
calld->got_initial_metadata = 1;
diff --git a/src/core/transport/chttp2/frame_data.c b/src/core/transport/chttp2/frame_data.c
index 7a4c355f23..40bf2ebd79 100644
--- a/src/core/transport/chttp2/frame_data.c
+++ b/src/core/transport/chttp2/frame_data.c
@@ -92,7 +92,7 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
p->frame_type = *cur;
switch (p->frame_type) {
case 0:
- /* noop */
+ p->is_frame_compressed = 0; /* GPR_FALSE */
break;
case 1:
p->is_frame_compressed = 1; /* GPR_TRUE */
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h
index e7901da510..f0eeb6de50 100644
--- a/src/core/transport/chttp2/internal.h
+++ b/src/core/transport/chttp2/internal.h
@@ -60,7 +60,6 @@ typedef enum {
GRPC_CHTTP2_LIST_WRITABLE,
GRPC_CHTTP2_LIST_WRITING,
GRPC_CHTTP2_LIST_WRITTEN,
- GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE,
GRPC_CHTTP2_LIST_PARSING_SEEN,
GRPC_CHTTP2_LIST_CLOSED_WAITING_FOR_PARSING,
GRPC_CHTTP2_LIST_CANCELLED_WAITING_FOR_WRITING,
@@ -383,6 +382,8 @@ typedef struct {
gpr_uint8 published_cancelled;
/** is this stream in the stream map? (boolean) */
gpr_uint8 in_stream_map;
+ /** is this stream actively being written? */
+ gpr_uint8 writing_now;
/** stream state already published to the upper layer */
grpc_stream_state published_state;
@@ -475,11 +476,17 @@ void grpc_chttp2_publish_reads(grpc_chttp2_transport_global *global,
void grpc_chttp2_list_add_writable_stream(
grpc_chttp2_transport_global *transport_global,
grpc_chttp2_stream_global *stream_global);
+void grpc_chttp2_list_add_first_writable_stream(
+ grpc_chttp2_transport_global *transport_global,
+ grpc_chttp2_stream_global *stream_global);
int grpc_chttp2_list_pop_writable_stream(
grpc_chttp2_transport_global *transport_global,
grpc_chttp2_transport_writing *transport_writing,
grpc_chttp2_stream_global **stream_global,
grpc_chttp2_stream_writing **stream_writing);
+void grpc_chttp2_list_remove_writable_stream(
+ grpc_chttp2_transport_global *transport_global,
+ grpc_chttp2_stream_global *stream_global);
void grpc_chttp2_list_add_incoming_window_updated(
grpc_chttp2_transport_global *transport_global,
@@ -511,18 +518,6 @@ int grpc_chttp2_list_pop_written_stream(
grpc_chttp2_stream_global **stream_global,
grpc_chttp2_stream_writing **stream_writing);
-void grpc_chttp2_list_add_writable_window_update_stream(
- grpc_chttp2_transport_global *transport_global,
- grpc_chttp2_stream_global *stream_global);
-int grpc_chttp2_list_pop_writable_window_update_stream(
- grpc_chttp2_transport_global *transport_global,
- grpc_chttp2_transport_writing *transport_writing,
- grpc_chttp2_stream_global **stream_global,
- grpc_chttp2_stream_writing **stream_writing);
-void grpc_chttp2_list_remove_writable_window_update_stream(
- grpc_chttp2_transport_global *transport_global,
- grpc_chttp2_stream_global *stream_global);
-
void grpc_chttp2_list_add_parsing_seen_stream(
grpc_chttp2_transport_parsing *transport_parsing,
grpc_chttp2_stream_parsing *stream_parsing);
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 904b9afce7..d84960009b 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -182,8 +182,7 @@ void grpc_chttp2_publish_reads(
stream_global->max_recv_bytes -=
stream_parsing->incoming_window_delta;
stream_parsing->incoming_window_delta = 0;
- grpc_chttp2_list_add_writable_window_update_stream(transport_global,
- stream_global);
+ grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
}
/* update outgoing flow control window */
@@ -607,7 +606,7 @@ static void on_header(void *tp, grpc_mdelem *md) {
}
grpc_chttp2_incoming_metadata_buffer_set_deadline(
&stream_parsing->incoming_metadata,
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), *cached_timeout));
+ gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), *cached_timeout));
GRPC_MDELEM_UNREF(md);
} else {
grpc_chttp2_incoming_metadata_buffer_add(&stream_parsing->incoming_metadata,
diff --git a/src/core/transport/chttp2/stream_lists.c b/src/core/transport/chttp2/stream_lists.c
index 590f6abfbc..9e68c1e146 100644
--- a/src/core/transport/chttp2/stream_lists.c
+++ b/src/core/transport/chttp2/stream_lists.c
@@ -108,6 +108,23 @@ static void stream_list_maybe_remove(grpc_chttp2_transport *t,
}
}
+static void stream_list_add_head(grpc_chttp2_transport *t,
+ grpc_chttp2_stream *s,
+ grpc_chttp2_stream_list_id id) {
+ grpc_chttp2_stream *old_head;
+ GPR_ASSERT(!s->included[id]);
+ old_head = t->lists[id].head;
+ s->links[id].next = old_head;
+ s->links[id].prev = NULL;
+ if (old_head) {
+ old_head->links[id].prev = s;
+ } else {
+ t->lists[id].tail = s;
+ }
+ t->lists[id].head = s;
+ s->included[id] = 1;
+}
+
static void stream_list_add_tail(grpc_chttp2_transport *t,
grpc_chttp2_stream *s,
grpc_chttp2_stream_list_id id) {
@@ -119,7 +136,6 @@ static void stream_list_add_tail(grpc_chttp2_transport *t,
if (old_tail) {
old_tail->links[id].next = s;
} else {
- s->links[id].prev = NULL;
t->lists[id].head = s;
}
t->lists[id].tail = s;
@@ -144,6 +160,18 @@ void grpc_chttp2_list_add_writable_stream(
STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_WRITABLE);
}
+void grpc_chttp2_list_add_first_writable_stream(
+ grpc_chttp2_transport_global *transport_global,
+ grpc_chttp2_stream_global *stream_global) {
+ GPR_ASSERT(stream_global->id != 0);
+ gpr_log(GPR_DEBUG, "add:%d:%d:%d:%d", stream_global->id,
+ stream_global->write_state, stream_global->in_stream_map,
+ stream_global->read_closed);
+ stream_list_add_head(TRANSPORT_FROM_GLOBAL(transport_global),
+ STREAM_FROM_GLOBAL(stream_global),
+ GRPC_CHTTP2_LIST_WRITABLE);
+}
+
int grpc_chttp2_list_pop_writable_stream(
grpc_chttp2_transport_global *transport_global,
grpc_chttp2_transport_writing *transport_writing,
@@ -157,6 +185,14 @@ int grpc_chttp2_list_pop_writable_stream(
return r;
}
+void grpc_chttp2_list_remove_writable_stream(
+ grpc_chttp2_transport_global *transport_global,
+ grpc_chttp2_stream_global *stream_global) {
+ stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
+ STREAM_FROM_GLOBAL(stream_global),
+ GRPC_CHTTP2_LIST_WRITABLE);
+}
+
void grpc_chttp2_list_add_writing_stream(
grpc_chttp2_transport_writing *transport_writing,
grpc_chttp2_stream_writing *stream_writing) {
@@ -202,36 +238,6 @@ int grpc_chttp2_list_pop_written_stream(
return r;
}
-void grpc_chttp2_list_add_writable_window_update_stream(
- grpc_chttp2_transport_global *transport_global,
- grpc_chttp2_stream_global *stream_global) {
- GPR_ASSERT(stream_global->id != 0);
- stream_list_add(TRANSPORT_FROM_GLOBAL(transport_global),
- STREAM_FROM_GLOBAL(stream_global),
- GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE);
-}
-
-int grpc_chttp2_list_pop_writable_window_update_stream(
- grpc_chttp2_transport_global *transport_global,
- grpc_chttp2_transport_writing *transport_writing,
- grpc_chttp2_stream_global **stream_global,
- grpc_chttp2_stream_writing **stream_writing) {
- grpc_chttp2_stream *stream;
- int r = stream_list_pop(TRANSPORT_FROM_GLOBAL(transport_global), &stream,
- GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE);
- *stream_global = &stream->global;
- *stream_writing = &stream->writing;
- return r;
-}
-
-void grpc_chttp2_list_remove_writable_window_update_stream(
- grpc_chttp2_transport_global *transport_global,
- grpc_chttp2_stream_global *stream_global) {
- stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global),
- STREAM_FROM_GLOBAL(stream_global),
- GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE);
-}
-
void grpc_chttp2_list_add_parsing_seen_stream(
grpc_chttp2_transport_parsing *transport_parsing,
grpc_chttp2_stream_parsing *stream_parsing) {
diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c
index d8ec117aa5..d39b0c42f7 100644
--- a/src/core/transport/chttp2/writing.c
+++ b/src/core/transport/chttp2/writing.c
@@ -44,6 +44,7 @@ int grpc_chttp2_unlocking_check_writes(
grpc_chttp2_transport_writing *transport_writing) {
grpc_chttp2_stream_global *stream_global;
grpc_chttp2_stream_writing *stream_writing;
+ grpc_chttp2_stream_global *first_reinserted_stream = NULL;
gpr_uint32 window_delta;
/* simple writes are queued to qbuf, and flushed here */
@@ -64,50 +65,54 @@ int grpc_chttp2_unlocking_check_writes(
}
/* for each grpc_chttp2_stream that's become writable, frame it's data
- (according to
- available window sizes) and add to the output buffer */
- while (grpc_chttp2_list_pop_writable_stream(transport_global,
- transport_writing, &stream_global,
- &stream_writing)) {
+ (according to available window sizes) and add to the output buffer */
+ while (grpc_chttp2_list_pop_writable_stream(
+ transport_global, transport_writing, &stream_global, &stream_writing)) {
+ if (stream_global == first_reinserted_stream) {
+ /* prevent infinite loop */
+ grpc_chttp2_list_add_first_writable_stream(transport_global,
+ stream_global);
+ break;
+ }
+
stream_writing->id = stream_global->id;
- window_delta = grpc_chttp2_preencode(
- stream_global->outgoing_sopb->ops, &stream_global->outgoing_sopb->nops,
- GPR_MIN(transport_global->outgoing_window,
- stream_global->outgoing_window),
- &stream_writing->sopb);
- GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT(
- "write", transport_global, outgoing_window, -(gpr_int64)window_delta);
- GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
- outgoing_window, -(gpr_int64)window_delta);
- transport_global->outgoing_window -= window_delta;
- stream_global->outgoing_window -= window_delta;
-
- if (stream_global->write_state == GRPC_WRITE_STATE_QUEUED_CLOSE &&
- stream_global->outgoing_sopb->nops == 0) {
- if (!transport_global->is_client && !stream_global->read_closed) {
- stream_writing->send_closed = GRPC_SEND_CLOSED_WITH_RST_STREAM;
- } else {
- stream_writing->send_closed = GRPC_SEND_CLOSED;
+ stream_writing->send_closed = GRPC_DONT_SEND_CLOSED;
+ GPR_ASSERT(!stream_global->writing_now);
+
+ if (stream_global->outgoing_sopb) {
+ window_delta =
+ grpc_chttp2_preencode(stream_global->outgoing_sopb->ops,
+ &stream_global->outgoing_sopb->nops,
+ GPR_MIN(transport_global->outgoing_window,
+ stream_global->outgoing_window),
+ &stream_writing->sopb);
+ GRPC_CHTTP2_FLOWCTL_TRACE_TRANSPORT(
+ "write", transport_global, outgoing_window, -(gpr_int64)window_delta);
+ GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
+ outgoing_window,
+ -(gpr_int64)window_delta);
+ transport_global->outgoing_window -= window_delta;
+ stream_global->outgoing_window -= window_delta;
+
+ if (stream_global->write_state == GRPC_WRITE_STATE_QUEUED_CLOSE &&
+ stream_global->outgoing_sopb->nops == 0) {
+ if (!transport_global->is_client && !stream_global->read_closed) {
+ stream_writing->send_closed = GRPC_SEND_CLOSED_WITH_RST_STREAM;
+ } else {
+ stream_writing->send_closed = GRPC_SEND_CLOSED;
+ }
}
- }
- if (stream_writing->sopb.nops > 0 ||
- stream_writing->send_closed != GRPC_DONT_SEND_CLOSED) {
- grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
- }
- if (stream_global->outgoing_window > 0 &&
- stream_global->outgoing_sopb->nops != 0) {
- grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ if (stream_global->outgoing_window > 0 &&
+ stream_global->outgoing_sopb->nops != 0) {
+ grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
+ if (first_reinserted_stream == NULL &&
+ transport_global->outgoing_window == 0) {
+ first_reinserted_stream = stream_global;
+ }
+ }
}
- }
- /* for each grpc_chttp2_stream that wants to update its window, add that
- * window here */
- while (grpc_chttp2_list_pop_writable_window_update_stream(transport_global,
- transport_writing,
- &stream_global,
- &stream_writing)) {
- stream_writing->id = stream_global->id;
if (!stream_global->read_closed && stream_global->unannounced_incoming_window > 0) {
stream_writing->announce_window = stream_global->unannounced_incoming_window;
GRPC_CHTTP2_FLOWCTL_TRACE_STREAM("write", transport_global, stream_global,
@@ -118,6 +123,11 @@ int grpc_chttp2_unlocking_check_writes(
stream_global->unannounced_incoming_window = 0;
grpc_chttp2_list_add_incoming_window_updated(transport_global,
stream_global);
+ stream_global->writing_now = 1;
+ grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
+ } else if (stream_writing->sopb.nops > 0 ||
+ stream_writing->send_closed != GRPC_DONT_SEND_CLOSED) {
+ stream_global->writing_now = 1;
grpc_chttp2_list_add_writing_stream(transport_writing, stream_writing);
}
}
@@ -205,6 +215,8 @@ void grpc_chttp2_cleanup_writing(
while (grpc_chttp2_list_pop_written_stream(
transport_global, transport_writing, &stream_global, &stream_writing)) {
+ GPR_ASSERT(stream_global->writing_now);
+ stream_global->writing_now = 0;
if (stream_global->outgoing_sopb != NULL &&
stream_global->outgoing_sopb->nops == 0) {
stream_global->outgoing_sopb = NULL;
@@ -216,9 +228,9 @@ void grpc_chttp2_cleanup_writing(
if (!transport_global->is_client) {
stream_global->read_closed = 1;
}
- grpc_chttp2_list_add_read_write_state_changed(transport_global,
- stream_global);
}
+ grpc_chttp2_list_add_read_write_state_changed(transport_global,
+ stream_global);
}
transport_writing->outbuf.count = 0;
transport_writing->outbuf.length = 0;
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 50718da281..ca100703d4 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -398,12 +398,16 @@ static void destroy_stream(grpc_transport *gt, grpc_stream *gs) {
}
grpc_chttp2_list_remove_incoming_window_updated(&t->global, &s->global);
- grpc_chttp2_list_remove_writable_window_update_stream(&t->global, &s->global);
+ grpc_chttp2_list_remove_writable_stream(&t->global, &s->global);
gpr_mu_unlock(&t->mu);
for (i = 0; i < STREAM_LIST_COUNT; i++) {
- GPR_ASSERT(!s->included[i]);
+ if (s->included[i]) {
+ gpr_log(GPR_ERROR, "%s stream %d still included in list %d",
+ t->global.is_client ? "client" : "server", s->global.id, i);
+ abort();
+ }
}
GPR_ASSERT(s->global.outgoing_sopb == NULL);
@@ -581,8 +585,6 @@ static void maybe_start_some_streams(
grpc_chttp2_list_add_incoming_window_updated(transport_global,
stream_global);
grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
- grpc_chttp2_list_add_writable_window_update_stream(transport_global,
- stream_global);
}
/* cancel out streams that will never be started */
@@ -648,8 +650,7 @@ static void perform_stream_op_locked(
if (stream_global->id != 0) {
grpc_chttp2_list_add_read_write_state_changed(transport_global,
stream_global);
- grpc_chttp2_list_add_writable_window_update_stream(transport_global,
- stream_global);
+ grpc_chttp2_list_add_writable_stream(transport_global, stream_global);
}
}
@@ -766,6 +767,7 @@ static void remove_stream(grpc_chttp2_transport *t, gpr_uint32 id) {
if (!s) {
s = grpc_chttp2_stream_map_delete(&t->new_stream_map, id);
}
+ grpc_chttp2_list_remove_writable_stream(&t->global, &s->global);
GPR_ASSERT(s);
s->global.in_stream_map = 0;
if (t->parsing.incoming_stream == &s->parsing) {
@@ -847,6 +849,9 @@ static void unlock_check_read_write_state(grpc_chttp2_transport *t) {
if (!stream_global->publish_sopb) {
continue;
}
+ if (stream_global->writing_now) {
+ continue;
+ }
/* FIXME(ctiller): we include in_stream_map in our computation of
whether the stream is write-closed. This is completely bogus,
but has the effect of delaying stream-closed until the stream
diff --git a/src/core/transport/transport_op_string.c b/src/core/transport/transport_op_string.c
index 10d796fc15..f62c340e97 100644
--- a/src/core/transport/transport_op_string.c
+++ b/src/core/transport/transport_op_string.c
@@ -116,10 +116,9 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) {
if (op->send_ops) {
if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
first = 0;
- gpr_strvec_add(&b, gpr_strdup("SEND"));
- if (op->is_last_send) {
- gpr_strvec_add(&b, gpr_strdup("_LAST"));
- }
+ gpr_asprintf(&tmp, "SEND%s:%p", op->is_last_send ? "_LAST" : "",
+ op->on_done_send);
+ gpr_strvec_add(&b, tmp);
gpr_strvec_add(&b, gpr_strdup("["));
gpr_strvec_add(&b, grpc_sopb_string(op->send_ops));
gpr_strvec_add(&b, gpr_strdup("]"));
@@ -128,7 +127,8 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) {
if (op->recv_ops) {
if (!first) gpr_strvec_add(&b, gpr_strdup(" "));
first = 0;
- gpr_asprintf(&tmp, "RECV:max_recv_bytes=%d", op->max_recv_bytes);
+ gpr_asprintf(&tmp, "RECV:%p:max_recv_bytes=%d", op->on_done_recv,
+ op->max_recv_bytes);
gpr_strvec_add(&b, tmp);
}
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 01c7f14f1a..abf0cb387e 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -99,8 +99,8 @@ std::shared_ptr<Credentials> ServiceAccountCredentials(
}
// Builds JWT credentials.
-std::shared_ptr<Credentials> JWTCredentials(const grpc::string& json_key,
- long token_lifetime_seconds) {
+std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
+ const grpc::string& json_key, long token_lifetime_seconds) {
if (token_lifetime_seconds <= 0) {
gpr_log(GPR_ERROR,
"Trying to create JWTCredentials with non-positive lifetime");
@@ -108,8 +108,8 @@ std::shared_ptr<Credentials> JWTCredentials(const grpc::string& json_key,
}
gpr_timespec lifetime =
gpr_time_from_seconds(token_lifetime_seconds, GPR_TIMESPAN);
- return WrapCredentials(
- grpc_jwt_credentials_create(json_key.c_str(), lifetime));
+ return WrapCredentials(grpc_service_account_jwt_access_credentials_create(
+ json_key.c_str(), lifetime));
}
// Builds refresh token credentials.
diff --git a/src/cpp/server/create_default_thread_pool.cc b/src/cpp/server/create_default_thread_pool.cc
index cc182f59f4..81c84474d8 100644
--- a/src/cpp/server/create_default_thread_pool.cc
+++ b/src/cpp/server/create_default_thread_pool.cc
@@ -32,7 +32,7 @@
*/
#include <grpc/support/cpu.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#ifndef GRPC_CUSTOM_DEFAULT_THREAD_POOL
@@ -41,7 +41,7 @@ namespace grpc {
ThreadPoolInterface* CreateDefaultThreadPool() {
int cores = gpr_cpu_num_cores();
if (!cores) cores = 4;
- return new FixedSizeThreadPool(cores);
+ return new DynamicThreadPool(cores);
}
} // namespace grpc
diff --git a/src/cpp/server/dynamic_thread_pool.cc b/src/cpp/server/dynamic_thread_pool.cc
new file mode 100644
index 0000000000..f58d0420df
--- /dev/null
+++ b/src/cpp/server/dynamic_thread_pool.cc
@@ -0,0 +1,131 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/impl/sync.h>
+#include <grpc++/impl/thd.h>
+#include <grpc++/dynamic_thread_pool.h>
+
+namespace grpc {
+DynamicThreadPool::DynamicThread::DynamicThread(DynamicThreadPool *pool):
+ pool_(pool),
+ thd_(new grpc::thread(&DynamicThreadPool::DynamicThread::ThreadFunc, this)) {
+}
+DynamicThreadPool::DynamicThread::~DynamicThread() {
+ thd_->join();
+ thd_.reset();
+}
+
+void DynamicThreadPool::DynamicThread::ThreadFunc() {
+ pool_->ThreadFunc();
+ // Now that we have killed ourselves, we should reduce the thread count
+ grpc::unique_lock<grpc::mutex> lock(pool_->mu_);
+ pool_->nthreads_--;
+ // Move ourselves to dead list
+ pool_->dead_threads_.push_back(this);
+
+ if ((pool_->shutdown_) && (pool_->nthreads_ == 0)) {
+ pool_->shutdown_cv_.notify_one();
+ }
+}
+
+void DynamicThreadPool::ThreadFunc() {
+ for (;;) {
+ // Wait until work is available or we are shutting down.
+ grpc::unique_lock<grpc::mutex> lock(mu_);
+ if (!shutdown_ && callbacks_.empty()) {
+ // If there are too many threads waiting, then quit this thread
+ if (threads_waiting_ >= reserve_threads_) {
+ break;
+ }
+ threads_waiting_++;
+ cv_.wait(lock);
+ threads_waiting_--;
+ }
+ // Drain callbacks before considering shutdown to ensure all work
+ // gets completed.
+ if (!callbacks_.empty()) {
+ auto cb = callbacks_.front();
+ callbacks_.pop();
+ lock.unlock();
+ cb();
+ } else if (shutdown_) {
+ break;
+ }
+ }
+}
+
+DynamicThreadPool::DynamicThreadPool(int reserve_threads) :
+ shutdown_(false), reserve_threads_(reserve_threads), nthreads_(0),
+ threads_waiting_(0) {
+ for (int i = 0; i < reserve_threads_; i++) {
+ grpc::lock_guard<grpc::mutex> lock(mu_);
+ nthreads_++;
+ new DynamicThread(this);
+ }
+}
+
+void DynamicThreadPool::ReapThreads(std::list<DynamicThread*>* tlist) {
+ for (auto t = tlist->begin(); t != tlist->end(); t = tlist->erase(t)) {
+ delete *t;
+ }
+}
+
+DynamicThreadPool::~DynamicThreadPool() {
+ grpc::unique_lock<grpc::mutex> lock(mu_);
+ shutdown_ = true;
+ cv_.notify_all();
+ while (nthreads_ != 0) {
+ shutdown_cv_.wait(lock);
+ }
+ ReapThreads(&dead_threads_);
+}
+
+void DynamicThreadPool::Add(const std::function<void()>& callback) {
+ grpc::lock_guard<grpc::mutex> lock(mu_);
+ // Add works to the callbacks list
+ callbacks_.push(callback);
+ // Increase pool size or notify as needed
+ if (threads_waiting_ == 0) {
+ // Kick off a new thread
+ nthreads_++;
+ new DynamicThread(this);
+ } else {
+ cv_.notify_one();
+ }
+ // Also use this chance to harvest dead threads
+ if (!dead_threads_.empty()) {
+ ReapThreads(&dead_threads_);
+ }
+}
+
+} // namespace grpc
diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc
index a814cad452..799c597e0b 100644
--- a/src/cpp/util/time.cc
+++ b/src/cpp/util/time.cc
@@ -79,9 +79,10 @@ void TimepointHR2Timespec(const high_resolution_clock::time_point& from,
}
system_clock::time_point Timespec2Timepoint(gpr_timespec t) {
- if (gpr_time_cmp(t, gpr_inf_future(GPR_CLOCK_REALTIME)) == 0) {
+ if (gpr_time_cmp(t, gpr_inf_future(t.clock_type)) == 0) {
return system_clock::time_point::max();
}
+ t = gpr_convert_clock_type(t, GPR_CLOCK_REALTIME);
system_clock::time_point tp;
tp += duration_cast<system_clock::time_point::duration>(seconds(t.tv_sec));
tp +=
diff --git a/src/csharp/Grpc.Auth/GoogleCredential.cs b/src/csharp/Grpc.Auth/GoogleCredential.cs
index 7edf19ed67..9936cf583c 100644
--- a/src/csharp/Grpc.Auth/GoogleCredential.cs
+++ b/src/csharp/Grpc.Auth/GoogleCredential.cs
@@ -89,17 +89,15 @@ namespace Grpc.Auth
return new GoogleCredential(new ComputeCredential(new ComputeCredential.Initializer()));
}
- JObject o1 = JObject.Parse(File.ReadAllText(credsPath));
- string clientEmail = o1.GetValue(ClientEmailFieldName).Value<string>();
- string privateKeyString = o1.GetValue(PrivateKeyFieldName).Value<string>();
- var privateKey = ParsePrivateKeyFromString(privateKeyString);
+ JObject jsonCredentialParameters = JObject.Parse(File.ReadAllText(credsPath));
+ string clientEmail = jsonCredentialParameters.GetValue(ClientEmailFieldName).Value<string>();
+ string privateKeyString = jsonCredentialParameters.GetValue(PrivateKeyFieldName).Value<string>();
var serviceCredential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(clientEmail)
{
Scopes = scopes,
- Key = privateKey
- });
+ }.FromPrivateKey(privateKeyString));
return new GoogleCredential(serviceCredential);
}
@@ -123,16 +121,5 @@ namespace Grpc.Auth
return credential;
}
}
-
- private RSACryptoServiceProvider ParsePrivateKeyFromString(string base64PrivateKey)
- {
- // TODO(jtattermusch): temporary code to create RSACryptoServiceProvider.
- base64PrivateKey = base64PrivateKey.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("\n", "").Replace("-----END PRIVATE KEY-----", "");
- RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(base64PrivateKey));
- RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters(key);
- RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
- rsa.ImportParameters(rsaParameters);
- return rsa;
- }
}
}
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index fdec2e7bd7..afb8204c07 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -11,6 +11,7 @@
<AssemblyName>Grpc.Auth</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<DocumentationFile>bin\$(Configuration)\Grpc.Auth.Xml</DocumentationFile>
+ <NuGetPackageImportStamp>9b408026</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -34,14 +35,17 @@
<Reference Include="BouncyCastle.Crypto">
<HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Auth">
- <HintPath>..\packages\Google.Apis.Auth.1.9.1\lib\net40\Google.Apis.Auth.dll</HintPath>
+ <Reference Include="Google.Apis.Auth, Version=1.9.2.27817, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Auth.PlatformServices">
- <HintPath>..\packages\Google.Apis.Auth.1.9.1\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+ <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.2.27820, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Core">
- <HintPath>..\packages\Google.Apis.Core.1.9.1\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+ <Reference Include="Google.Apis.Core, Version=1.9.2.27816, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Google.Apis.Core.1.9.2\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Threading.Tasks">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
@@ -52,18 +56,20 @@
<Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
<HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
</Reference>
- <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
- <Reference Include="System.Net.Http.Extensions">
- <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Extensions.dll</HintPath>
+ <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
</Reference>
- <Reference Include="System.Net.Http.Primitives">
- <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Primitives.dll</HintPath>
+ <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
</ItemGroup>
@@ -87,9 +93,11 @@
<None Include="Grpc.Auth.nuspec" />
<None Include="packages.config" />
</ItemGroup>
- <Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
- <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
- <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
- <Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
+ <Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
index 1262bdbdab..eeaa49aa92 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
@@ -15,8 +15,7 @@
<copyright>Copyright 2015, Google Inc.</copyright>
<tags>gRPC RPC Protocol HTTP/2 Auth OAuth2</tags>
<dependencies>
- <dependency id="BouncyCastle" version="1.7.0" />
- <dependency id="Google.Apis.Auth" version="1.9.1" />
+ <dependency id="Google.Apis.Auth" version="1.9.2" />
<dependency id="Grpc.Core" version="$version$" />
</dependencies>
</metadata>
diff --git a/src/csharp/Grpc.Auth/app.config b/src/csharp/Grpc.Auth/app.config
index 966b777192..0a82bb4f16 100644
--- a/src/csharp/Grpc.Auth/app.config
+++ b/src/csharp/Grpc.Auth/app.config
@@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+ <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config
index 7d348872ba..29be953bf3 100644
--- a/src/csharp/Grpc.Auth/packages.config
+++ b/src/csharp/Grpc.Auth/packages.config
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
- <package id="Google.Apis.Auth" version="1.9.1" targetFramework="net45" />
- <package id="Google.Apis.Core" version="1.9.1" targetFramework="net45" />
- <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
+ <package id="Google.Apis.Auth" version="1.9.2" targetFramework="net45" />
+ <package id="Google.Apis.Core" version="1.9.2" targetFramework="net45" />
+ <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
- <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
- <package id="Microsoft.Net.Http" version="2.2.28" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="6.0.6" targetFramework="net45" />
+ <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
+ <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index 8ba2c8a9a2..e286ea519f 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -45,7 +45,7 @@ namespace Grpc.Core.Tests
{
public class ClientServerTest
{
- const string Host = "localhost";
+ const string Host = "127.0.0.1";
const string ServiceName = "/tests.Test";
static readonly Method<string, string> EchoMethod = new Method<string, string>(
@@ -79,9 +79,9 @@ namespace Grpc.Core.Tests
{
server = new Server();
server.AddServiceDefinition(ServiceDefinition);
- int port = server.AddListeningPort(Host, Server.PickUnusedPort);
+ int port = server.AddPort(Host, Server.PickUnusedPort, ServerCredentials.Insecure);
server.Start();
- channel = new Channel(Host, port);
+ channel = new Channel(Host, port, Credentials.Insecure);
}
[TearDown]
@@ -158,59 +158,50 @@ namespace Grpc.Core.Tests
}
[Test]
- public void AsyncUnaryCall_ServerHandlerThrows()
+ public async Task AsyncUnaryCall_ServerHandlerThrows()
{
- Task.Run(async () =>
+ var internalCall = new Call<string, string>(ServiceName, EchoMethod, channel, Metadata.Empty);
+ try
{
- var internalCall = new Call<string, string>(ServiceName, EchoMethod, channel, Metadata.Empty);
- try
- {
- await Calls.AsyncUnaryCall(internalCall, "THROW", CancellationToken.None);
- Assert.Fail();
- }
- catch (RpcException e)
- {
- Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
- }
- }).Wait();
+ await Calls.AsyncUnaryCall(internalCall, "THROW", CancellationToken.None);
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
+ }
}
[Test]
- public void ClientStreamingCall()
+ public async Task ClientStreamingCall()
{
- Task.Run(async () =>
- {
- var internalCall = new Call<string, string>(ServiceName, ConcatAndEchoMethod, channel, Metadata.Empty);
- var call = Calls.AsyncClientStreamingCall(internalCall, CancellationToken.None);
+ var internalCall = new Call<string, string>(ServiceName, ConcatAndEchoMethod, channel, Metadata.Empty);
+ var call = Calls.AsyncClientStreamingCall(internalCall, CancellationToken.None);
- await call.RequestStream.WriteAll(new string[] { "A", "B", "C" });
- Assert.AreEqual("ABC", await call.ResponseAsync);
- }).Wait();
+ await call.RequestStream.WriteAll(new string[] { "A", "B", "C" });
+ Assert.AreEqual("ABC", await call.ResponseAsync);
}
[Test]
- public void ClientStreamingCall_CancelAfterBegin()
+ public async Task ClientStreamingCall_CancelAfterBegin()
{
- Task.Run(async () =>
- {
- var internalCall = new Call<string, string>(ServiceName, ConcatAndEchoMethod, channel, Metadata.Empty);
+ var internalCall = new Call<string, string>(ServiceName, ConcatAndEchoMethod, channel, Metadata.Empty);
- var cts = new CancellationTokenSource();
- var call = Calls.AsyncClientStreamingCall(internalCall, cts.Token);
+ var cts = new CancellationTokenSource();
+ var call = Calls.AsyncClientStreamingCall(internalCall, cts.Token);
- // TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
- await Task.Delay(1000);
- cts.Cancel();
+ // TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
+ await Task.Delay(1000);
+ cts.Cancel();
- try
- {
- await call.ResponseAsync;
- }
- catch (RpcException e)
- {
- Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
- }
- }).Wait();
+ try
+ {
+ await call.ResponseAsync;
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
+ }
}
[Test]
@@ -277,6 +268,14 @@ namespace Grpc.Core.Tests
Assert.IsTrue(userAgent.StartsWith("grpc-csharp/"));
}
+ [Test]
+ public void PeerInfoPresent()
+ {
+ var internalCall = new Call<string, string>(ServiceName, EchoMethod, channel, Metadata.Empty);
+ string peer = Calls.BlockingUnaryCall(internalCall, "RETURN-PEER", CancellationToken.None);
+ Assert.IsTrue(peer.Contains(Host));
+ }
+
private static async Task<string> EchoHandler(string request, ServerCallContext context)
{
foreach (Metadata.Entry metadataEntry in context.RequestHeaders)
@@ -292,6 +291,11 @@ namespace Grpc.Core.Tests
return context.RequestHeaders.Where(entry => entry.Key == "user-agent").Single().Value;
}
+ if (request == "RETURN-PEER")
+ {
+ return context.Peer;
+ }
+
if (request == "THROW")
{
throw new Exception("This was thrown on purpose by a test");
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index 927954c448..1c4cca8b69 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -28,9 +28,25 @@
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="nunit.core">
+ <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
+ <Reference Include="nunit.core.interfaces">
+ <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
+ <Reference Include="nunit.util">
+ <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
+ <Reference Include="NUnit.VisualStudio.TestAdapter">
+ <HintPath>..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async">
<HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
@@ -44,13 +60,15 @@
<Compile Include="ClientServerTest.cs" />
<Compile Include="ServerTest.cs" />
<Compile Include="GrpcEnvironmentTest.cs" />
- <Compile Include="TimespecTest.cs" />
<Compile Include="PInvokeTest.cs" />
<Compile Include="Internal\MetadataArraySafeHandleTest.cs" />
<Compile Include="Internal\CompletionQueueSafeHandleTest.cs" />
<Compile Include="Internal\CompletionQueueEventTest.cs" />
<Compile Include="Internal\ChannelArgsSafeHandleTest.cs" />
<Compile Include="ChannelOptionsTest.cs" />
+ <Compile Include="Internal\TimespecTest.cs" />
+ <Compile Include="TimeoutsTest.cs" />
+ <Compile Include="NUnitVersionTest.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -60,7 +78,9 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
- <None Include="packages.config" />
+ <None Include="packages.config">
+ <SubType>Designer</SubType>
+ </None>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
diff --git a/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs b/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs
new file mode 100644
index 0000000000..874df02baa
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/Internal/TimespecTest.cs
@@ -0,0 +1,202 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+using Grpc.Core.Internal;
+using NUnit.Framework;
+
+namespace Grpc.Core.Internal.Tests
+{
+ public class TimespecTest
+ {
+ [Test]
+ public void Now_IsInUtc()
+ {
+ Assert.AreEqual(DateTimeKind.Utc, Timespec.Now.ToDateTime().Kind);
+ }
+
+ [Test]
+ public void Now_AgreesWithUtcNow()
+ {
+ var timespec = Timespec.Now;
+ var utcNow = DateTime.UtcNow;
+
+ TimeSpan difference = utcNow - timespec.ToDateTime();
+
+ // This test is inherently a race - but the two timestamps
+ // should really be way less that a minute apart.
+ Assert.IsTrue(difference.TotalSeconds < 60);
+ }
+
+ [Test]
+ public void InfFuture()
+ {
+ var timespec = Timespec.InfFuture;
+ }
+
+ [Test]
+ public void InfPast()
+ {
+ var timespec = Timespec.InfPast;
+ }
+
+ [Test]
+ public void TimespecSizeIsNativeSize()
+ {
+ Assert.AreEqual(Timespec.NativeSize, Marshal.SizeOf(typeof(Timespec)));
+ }
+
+ [Test]
+ public void ToDateTime()
+ {
+ Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
+ new Timespec(IntPtr.Zero, 0).ToDateTime());
+
+ Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50),
+ new Timespec(new IntPtr(10), 5000).ToDateTime());
+
+ Assert.AreEqual(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc),
+ new Timespec(new IntPtr(1437452508), 0).ToDateTime());
+
+ // before epoch
+ Assert.AreEqual(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10),
+ new Timespec(new IntPtr(-5), 1000).ToDateTime());
+
+ // infinity
+ Assert.AreEqual(DateTime.MaxValue, Timespec.InfFuture.ToDateTime());
+ Assert.AreEqual(DateTime.MinValue, Timespec.InfPast.ToDateTime());
+
+ // nanos are rounded to ticks are rounded up
+ Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(1),
+ new Timespec(IntPtr.Zero, 99).ToDateTime());
+
+ // Illegal inputs
+ Assert.Throws(typeof(InvalidOperationException),
+ () => new Timespec(new IntPtr(0), -2).ToDateTime());
+ Assert.Throws(typeof(InvalidOperationException),
+ () => new Timespec(new IntPtr(0), 1000 * 1000 * 1000).ToDateTime());
+ Assert.Throws(typeof(InvalidOperationException),
+ () => new Timespec(new IntPtr(0), 0, GPRClockType.Monotonic).ToDateTime());
+ }
+
+ [Test]
+ public void ToDateTime_ReturnsUtc()
+ {
+ Assert.AreEqual(DateTimeKind.Utc, new Timespec(new IntPtr(1437452508), 0).ToDateTime().Kind);
+ Assert.AreNotEqual(DateTimeKind.Unspecified, new Timespec(new IntPtr(1437452508), 0).ToDateTime().Kind);
+ }
+
+ [Test]
+ public void ToDateTime_Overflow()
+ {
+ // we can only get overflow in ticks arithmetic on 64-bit
+ if (IntPtr.Size == 8)
+ {
+ var timespec = new Timespec(new IntPtr(long.MaxValue - 100), 0);
+ Assert.AreNotEqual(Timespec.InfFuture, timespec);
+ Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
+
+ Assert.AreEqual(DateTime.MinValue, new Timespec(new IntPtr(long.MinValue + 100), 0).ToDateTime());
+ }
+ else
+ {
+ Console.WriteLine("Test cannot be run on this platform, skipping the test.");
+ }
+ }
+
+ [Test]
+ public void ToDateTime_OutOfDateTimeRange()
+ {
+ // we can only get out of range on 64-bit, on 32 bit the max
+ // timestamp is ~ Jan 19 2038, which is far within range of DateTime
+ // same case for min value.
+ if (IntPtr.Size == 8)
+ {
+ // DateTime range goes up to year 9999, 20000 years from now should
+ // be out of range.
+ long seconds = 20000L * 365L * 24L * 3600L;
+
+ var timespec = new Timespec(new IntPtr(seconds), 0);
+ Assert.AreNotEqual(Timespec.InfFuture, timespec);
+ Assert.AreEqual(DateTime.MaxValue, timespec.ToDateTime());
+
+ Assert.AreEqual(DateTime.MinValue, new Timespec(new IntPtr(-seconds), 0).ToDateTime());
+ }
+ else
+ {
+ Console.WriteLine("Test cannot be run on this platform, skipping the test");
+ }
+ }
+
+ [Test]
+ public void FromDateTime()
+ {
+ Assert.AreEqual(new Timespec(IntPtr.Zero, 0),
+ Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
+
+ Assert.AreEqual(new Timespec(new IntPtr(10), 5000),
+ Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50)));
+
+ Assert.AreEqual(new Timespec(new IntPtr(1437452508), 0),
+ Timespec.FromDateTime(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc)));
+
+ // before epoch
+ Assert.AreEqual(new Timespec(new IntPtr(-5), 1000),
+ Timespec.FromDateTime(new DateTime(1969, 12, 31, 23, 59, 55, DateTimeKind.Utc).AddTicks(10)));
+
+ // infinity
+ Assert.AreEqual(Timespec.InfFuture, Timespec.FromDateTime(DateTime.MaxValue));
+ Assert.AreEqual(Timespec.InfPast, Timespec.FromDateTime(DateTime.MinValue));
+
+ // illegal inputs
+ Assert.Throws(typeof(ArgumentException),
+ () => Timespec.FromDateTime(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Unspecified)));
+ }
+
+ [Test]
+ public void FromDateTime_OutOfTimespecRange()
+ {
+ // we can only get overflow in Timespec on 32-bit
+ if (IntPtr.Size == 4)
+ {
+ Assert.AreEqual(Timespec.InfFuture, Timespec.FromDateTime(new DateTime(2040, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
+ Assert.AreEqual(Timespec.InfPast, Timespec.FromDateTime(new DateTime(1800, 1, 1, 0, 0, 0, DateTimeKind.Utc)));
+ }
+ else
+ {
+ Console.WriteLine("Test cannot be run on this platform, skipping the test.");
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs b/src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs
new file mode 100644
index 0000000000..600df1a18d
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/NUnitVersionTest.cs
@@ -0,0 +1,79 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+ /// <summary>
+ /// Tests if the version of nunit-console used is sufficient to run async tests.
+ /// </summary>
+ public class NUnitVersionTest
+ {
+ private int testRunCount = 0;
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ if (testRunCount != 2)
+ {
+ Console.Error.WriteLine("You are using and old version of NUnit that doesn't support async tests and skips them instead. " +
+ "This test has failed to indicate that.");
+ Console.Error.Flush();
+ Environment.Exit(1);
+ }
+ }
+
+ [Test]
+ public void NUnitVersionTest1()
+ {
+ testRunCount++;
+ }
+
+ // Old version of NUnit will skip this test
+ [Test]
+ public async Task NUnitVersionTest2()
+ {
+ testRunCount ++;
+ await Task.Delay(10);
+ }
+
+
+ }
+}
diff --git a/src/csharp/Grpc.Core.Tests/ServerTest.cs b/src/csharp/Grpc.Core.Tests/ServerTest.cs
index 1119aa370e..ba9efae871 100644
--- a/src/csharp/Grpc.Core.Tests/ServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ServerTest.cs
@@ -45,7 +45,7 @@ namespace Grpc.Core.Tests
public void StartAndShutdownServer()
{
Server server = new Server();
- server.AddListeningPort("localhost", Server.PickUnusedPort);
+ server.AddPort("localhost", Server.PickUnusedPort, ServerCredentials.Insecure);
server.Start();
server.ShutdownAsync().Wait();
GrpcEnvironment.Shutdown();
diff --git a/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
new file mode 100644
index 0000000000..010ffd898a
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/TimeoutsTest.cs
@@ -0,0 +1,207 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+ /// <summary>
+ /// Tests for Deadline support.
+ /// </summary>
+ public class TimeoutsTest
+ {
+ const string Host = "localhost";
+ const string ServiceName = "/tests.Test";
+
+ static readonly Method<string, string> TestMethod = new Method<string, string>(
+ MethodType.Unary,
+ "/tests.Test/Test",
+ Marshallers.StringMarshaller,
+ Marshallers.StringMarshaller);
+
+ static readonly ServerServiceDefinition ServiceDefinition = ServerServiceDefinition.CreateBuilder(ServiceName)
+ .AddMethod(TestMethod, TestMethodHandler)
+ .Build();
+
+ // provides a way how to retrieve an out-of-band result value from server handler
+ static TaskCompletionSource<string> stringFromServerHandlerTcs;
+
+ Server server;
+ Channel channel;
+
+ [SetUp]
+ public void Init()
+ {
+ server = new Server();
+ server.AddServiceDefinition(ServiceDefinition);
+ int port = server.AddPort(Host, Server.PickUnusedPort, ServerCredentials.Insecure);
+ server.Start();
+ channel = new Channel(Host, port, Credentials.Insecure);
+
+ stringFromServerHandlerTcs = new TaskCompletionSource<string>();
+ }
+
+ [TearDown]
+ public void Cleanup()
+ {
+ channel.Dispose();
+ server.ShutdownAsync().Wait();
+ }
+
+ [TestFixtureTearDown]
+ public void CleanupClass()
+ {
+ GrpcEnvironment.Shutdown();
+ }
+
+ [Test]
+ public void InfiniteDeadline()
+ {
+ // no deadline specified, check server sees infinite deadline
+ var internalCall = new Call<string, string>(ServiceName, TestMethod, channel, Metadata.Empty);
+ Assert.AreEqual("DATETIME_MAXVALUE", Calls.BlockingUnaryCall(internalCall, "RETURN_DEADLINE", CancellationToken.None));
+
+ // DateTime.MaxValue deadline specified, check server sees infinite deadline
+ var internalCall2 = new Call<string, string>(ServiceName, TestMethod, channel, Metadata.Empty, DateTime.MaxValue);
+ Assert.AreEqual("DATETIME_MAXVALUE", Calls.BlockingUnaryCall(internalCall2, "RETURN_DEADLINE", CancellationToken.None));
+ }
+
+ [Test]
+ public void DeadlineTransferredToServer()
+ {
+ var remainingTimeClient = TimeSpan.FromDays(7);
+ var deadline = DateTime.UtcNow + remainingTimeClient;
+ Thread.Sleep(1000);
+ var internalCall = new Call<string, string>(ServiceName, TestMethod, channel, Metadata.Empty, deadline);
+
+ var serverDeadlineTicksString = Calls.BlockingUnaryCall(internalCall, "RETURN_DEADLINE", CancellationToken.None);
+ var serverDeadline = new DateTime(long.Parse(serverDeadlineTicksString), DateTimeKind.Utc);
+
+ // A fairly relaxed check that the deadline set by client and deadline seen by server
+ // are in agreement. C core takes care of the work with transferring deadline over the wire,
+ // so we don't need an exact check here.
+ Assert.IsTrue(Math.Abs((deadline - serverDeadline).TotalMilliseconds) < 5000);
+ }
+
+ [Test]
+ public void DeadlineInThePast()
+ {
+ var deadline = DateTime.MinValue;
+ var internalCall = new Call<string, string>(ServiceName, TestMethod, channel, Metadata.Empty, deadline);
+
+ try
+ {
+ Calls.BlockingUnaryCall(internalCall, "TIMEOUT", CancellationToken.None);
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.DeadlineExceeded, e.Status.StatusCode);
+ }
+ }
+
+ [Test]
+ public void DeadlineExceededStatusOnTimeout()
+ {
+ var deadline = DateTime.UtcNow.Add(TimeSpan.FromSeconds(5));
+ var internalCall = new Call<string, string>(ServiceName, TestMethod, channel, Metadata.Empty, deadline);
+
+ try
+ {
+ Calls.BlockingUnaryCall(internalCall, "TIMEOUT", CancellationToken.None);
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.DeadlineExceeded, e.Status.StatusCode);
+ }
+ }
+
+ [Test]
+ public void ServerReceivesCancellationOnTimeout()
+ {
+ var deadline = DateTime.UtcNow.Add(TimeSpan.FromSeconds(5));
+ var internalCall = new Call<string, string>(ServiceName, TestMethod, channel, Metadata.Empty, deadline);
+
+ try
+ {
+ Calls.BlockingUnaryCall(internalCall, "CHECK_CANCELLATION_RECEIVED", CancellationToken.None);
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.DeadlineExceeded, e.Status.StatusCode);
+ }
+ Assert.AreEqual("CANCELLED", stringFromServerHandlerTcs.Task.Result);
+ }
+
+ private static async Task<string> TestMethodHandler(string request, ServerCallContext context)
+ {
+ if (request == "TIMEOUT")
+ {
+ await Task.Delay(60000);
+ return "";
+ }
+
+ if (request == "RETURN_DEADLINE")
+ {
+ if (context.Deadline == DateTime.MaxValue)
+ {
+ return "DATETIME_MAXVALUE";
+ }
+
+ return context.Deadline.Ticks.ToString();
+ }
+
+ if (request == "CHECK_CANCELLATION_RECEIVED")
+ {
+ // wait until cancellation token is fired.
+ var tcs = new TaskCompletionSource<object>();
+ context.CancellationToken.Register(() => { tcs.SetResult(null); });
+ await tcs.Task;
+ stringFromServerHandlerTcs.SetResult("CANCELLED");
+ return "";
+ }
+
+ return "";
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core.Tests/TimespecTest.cs b/src/csharp/Grpc.Core.Tests/TimespecTest.cs
deleted file mode 100644
index a34b407a01..0000000000
--- a/src/csharp/Grpc.Core.Tests/TimespecTest.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-#region Copyright notice and license
-
-// 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.
-
-#endregion
-
-using System;
-using System.Runtime.InteropServices;
-using Grpc.Core.Internal;
-using NUnit.Framework;
-
-namespace Grpc.Core.Internal.Tests
-{
- public class TimespecTest
- {
- [Test]
- public void Now()
- {
- var timespec = Timespec.Now;
- }
-
- [Test]
- public void InfFuture()
- {
- var timespec = Timespec.InfFuture;
- }
-
- [Test]
- public void TimespecSizeIsNativeSize()
- {
- Assert.AreEqual(Timespec.NativeSize, Marshal.SizeOf(typeof(Timespec)));
- }
-
- [Test]
- public void ToDateTime()
- {
- Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc),
- new Timespec(IntPtr.Zero, 0).ToDateTime());
-
- Assert.AreEqual(new DateTime(1970, 1, 1, 0, 0, 10, DateTimeKind.Utc).AddTicks(50),
- new Timespec(new IntPtr(10), 5000).ToDateTime());
-
- Assert.AreEqual(new DateTime(2015, 7, 21, 4, 21, 48, DateTimeKind.Utc),
- new Timespec(new IntPtr(1437452508), 0).ToDateTime());
- }
-
- [Test]
- public void Add()
- {
- var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = 123456789 };
- var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10));
- Assert.AreEqual(result.tv_sec, new IntPtr(12355));
- Assert.AreEqual(result.tv_nsec, 123456789);
- }
-
- [Test]
- public void Add_Nanos()
- {
- var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = 123456789 };
- var result = t.Add(TimeSpan.FromTicks(10));
- Assert.AreEqual(result.tv_sec, new IntPtr(12345));
- Assert.AreEqual(result.tv_nsec, 123456789 + 1000);
- }
-
- [Test]
- public void Add_NanosOverflow()
- {
- var t = new Timespec { tv_sec = new IntPtr(12345), tv_nsec = 999999999 };
- var result = t.Add(TimeSpan.FromTicks(TimeSpan.TicksPerSecond * 10 + 10));
- Assert.AreEqual(result.tv_sec, new IntPtr(12356));
- Assert.AreEqual(result.tv_nsec, 999);
- }
- }
-}
diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config
index 28af8d78c6..62077f41be 100644
--- a/src/csharp/Grpc.Core.Tests/packages.config
+++ b/src/csharp/Grpc.Core.Tests/packages.config
@@ -2,4 +2,5 @@
<packages>
<package id="Ix-Async" version="1.2.3" targetFramework="net45" />
<package id="NUnit" version="2.6.4" targetFramework="net45" />
+ <package id="NUnitTestAdapter" version="2.0.0" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/Call.cs b/src/csharp/Grpc.Core/Call.cs
index 37b452f020..94c5e26082 100644
--- a/src/csharp/Grpc.Core/Call.cs
+++ b/src/csharp/Grpc.Core/Call.cs
@@ -47,14 +47,21 @@ namespace Grpc.Core
readonly Marshaller<TResponse> responseMarshaller;
readonly Channel channel;
readonly Metadata headers;
+ readonly DateTime deadline;
public Call(string serviceName, Method<TRequest, TResponse> method, Channel channel, Metadata headers)
+ : this(serviceName, method, channel, headers, DateTime.MaxValue)
+ {
+ }
+
+ public Call(string serviceName, Method<TRequest, TResponse> method, Channel channel, Metadata headers, DateTime deadline)
{
this.name = method.GetFullName(serviceName);
this.requestMarshaller = method.RequestMarshaller;
this.responseMarshaller = method.ResponseMarshaller;
this.channel = Preconditions.CheckNotNull(channel);
this.headers = Preconditions.CheckNotNull(headers);
+ this.deadline = deadline;
}
public Channel Channel
@@ -87,6 +94,14 @@ namespace Grpc.Core
}
}
+ public DateTime Deadline
+ {
+ get
+ {
+ return this.deadline;
+ }
+ }
+
public Marshaller<TRequest> RequestMarshaller
{
get
diff --git a/src/csharp/Grpc.Core/Calls.cs b/src/csharp/Grpc.Core/Calls.cs
index 359fe53741..054fc27491 100644
--- a/src/csharp/Grpc.Core/Calls.cs
+++ b/src/csharp/Grpc.Core/Calls.cs
@@ -50,7 +50,7 @@ namespace Grpc.Core
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
// TODO(jtattermusch): this gives a race that cancellation can be requested before the call even starts.
RegisterCancellationCallback(asyncCall, token);
- return asyncCall.UnaryCall(call.Channel, call.Name, req, call.Headers);
+ return asyncCall.UnaryCall(call.Channel, call.Name, req, call.Headers, call.Deadline);
}
public static AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
@@ -58,8 +58,8 @@ namespace Grpc.Core
where TResponse : class
{
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
- asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name);
- var asyncResult = asyncCall.UnaryCallAsync(req, call.Headers);
+ asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name, Timespec.FromDateTime(call.Deadline));
+ var asyncResult = asyncCall.UnaryCallAsync(req, call.Headers, call.Deadline);
RegisterCancellationCallback(asyncCall, token);
return new AsyncUnaryCall<TResponse>(asyncResult, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
}
@@ -69,8 +69,8 @@ namespace Grpc.Core
where TResponse : class
{
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
- asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name);
- asyncCall.StartServerStreamingCall(req, call.Headers);
+ asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name, Timespec.FromDateTime(call.Deadline));
+ asyncCall.StartServerStreamingCall(req, call.Headers, call.Deadline);
RegisterCancellationCallback(asyncCall, token);
var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
return new AsyncServerStreamingCall<TResponse>(responseStream, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
@@ -81,8 +81,8 @@ namespace Grpc.Core
where TResponse : class
{
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
- asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name);
- var resultTask = asyncCall.ClientStreamingCallAsync(call.Headers);
+ asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name, Timespec.FromDateTime(call.Deadline));
+ var resultTask = asyncCall.ClientStreamingCallAsync(call.Headers, call.Deadline);
RegisterCancellationCallback(asyncCall, token);
var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
return new AsyncClientStreamingCall<TRequest, TResponse>(requestStream, resultTask, asyncCall.GetStatus, asyncCall.GetTrailers, asyncCall.Cancel);
@@ -93,8 +93,8 @@ namespace Grpc.Core
where TResponse : class
{
var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestMarshaller.Serializer, call.ResponseMarshaller.Deserializer);
- asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name);
- asyncCall.StartDuplexStreamingCall(call.Headers);
+ asyncCall.Initialize(call.Channel, call.Channel.CompletionQueue, call.Name, Timespec.FromDateTime(call.Deadline));
+ asyncCall.StartDuplexStreamingCall(call.Headers, call.Deadline);
RegisterCancellationCallback(asyncCall, token);
var requestStream = new ClientRequestStream<TRequest, TResponse>(asyncCall);
var responseStream = new ClientResponseStream<TRequest, TResponse>(asyncCall);
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index e5c6abd2cb..18e6f2fda5 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -56,26 +56,24 @@ namespace Grpc.Core
/// Port will default to 80 for an unsecure channel and to 443 a secure channel.
/// </summary>
/// <param name="host">The DNS name of IP address of the host.</param>
- /// <param name="credentials">Optional credentials to create a secure channel.</param>
+ /// <param name="credentials">Credentials to secure the channel.</param>
/// <param name="options">Channel options.</param>
- public Channel(string host, Credentials credentials = null, IEnumerable<ChannelOption> options = null)
+ public Channel(string host, Credentials credentials, IEnumerable<ChannelOption> options = null)
{
this.environment = GrpcEnvironment.GetInstance();
this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
EnsureUserAgentChannelOption(this.options);
+ using (CredentialsSafeHandle nativeCredentials = credentials.ToNativeCredentials())
using (ChannelArgsSafeHandle nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options))
{
- if (credentials != null)
+ if (nativeCredentials != null)
{
- using (CredentialsSafeHandle nativeCredentials = credentials.ToNativeCredentials())
- {
- this.handle = ChannelSafeHandle.CreateSecure(nativeCredentials, host, nativeChannelArgs);
- }
+ this.handle = ChannelSafeHandle.CreateSecure(nativeCredentials, host, nativeChannelArgs);
}
else
{
- this.handle = ChannelSafeHandle.Create(host, nativeChannelArgs);
+ this.handle = ChannelSafeHandle.CreateInsecure(host, nativeChannelArgs);
}
}
this.target = GetOverridenTarget(host, this.options);
@@ -86,9 +84,9 @@ namespace Grpc.Core
/// </summary>
/// <param name="host">DNS name or IP address</param>
/// <param name="port">the port</param>
- /// <param name="credentials">Optional credentials to create a secure channel.</param>
+ /// <param name="credentials">Credentials to secure the channel.</param>
/// <param name="options">Channel options.</param>
- public Channel(string host, int port, Credentials credentials = null, IEnumerable<ChannelOption> options = null) :
+ public Channel(string host, int port, Credentials credentials, IEnumerable<ChannelOption> options = null) :
this(string.Format("{0}:{1}", host, port), credentials, options)
{
}
diff --git a/src/csharp/Grpc.Core/ClientBase.cs b/src/csharp/Grpc.Core/ClientBase.cs
index a099f96aea..fd3473128a 100644
--- a/src/csharp/Grpc.Core/ClientBase.cs
+++ b/src/csharp/Grpc.Core/ClientBase.cs
@@ -76,7 +76,7 @@ namespace Grpc.Core
/// <summary>
/// Creates a new call to given method.
/// </summary>
- protected Call<TRequest, TResponse> CreateCall<TRequest, TResponse>(string serviceName, Method<TRequest, TResponse> method, Metadata metadata)
+ protected Call<TRequest, TResponse> CreateCall<TRequest, TResponse>(string serviceName, Method<TRequest, TResponse> method, Metadata metadata, DateTime? deadline)
where TRequest : class
where TResponse : class
{
@@ -87,8 +87,8 @@ namespace Grpc.Core
interceptor(metadata);
metadata.Freeze();
}
- metadata = metadata ?? Metadata.Empty;
- return new Call<TRequest, TResponse>(serviceName, method, channel, metadata);
+ return new Call<TRequest, TResponse>(serviceName, method, channel,
+ metadata ?? Metadata.Empty, deadline ?? DateTime.MaxValue);
}
}
}
diff --git a/src/csharp/Grpc.Core/Credentials.cs b/src/csharp/Grpc.Core/Credentials.cs
index e64c1e3dc1..4fcac0c4c0 100644
--- a/src/csharp/Grpc.Core/Credentials.cs
+++ b/src/csharp/Grpc.Core/Credentials.cs
@@ -41,39 +41,98 @@ namespace Grpc.Core
/// </summary>
public abstract class Credentials
{
+ static readonly Credentials InsecureInstance = new InsecureCredentialsImpl();
+
+ /// <summary>
+ /// Returns instance of credential that provides no security and
+ /// will result in creating an unsecure channel with no encryption whatsoever.
+ /// </summary>
+ public static Credentials Insecure
+ {
+ get
+ {
+ return InsecureInstance;
+ }
+ }
+
/// <summary>
- /// Creates native object for the credentials.
+ /// Creates native object for the credentials. May return null if insecure channel
+ /// should be created.
/// </summary>
/// <returns>The native credentials.</returns>
internal abstract CredentialsSafeHandle ToNativeCredentials();
+
+ private sealed class InsecureCredentialsImpl : Credentials
+ {
+ internal override CredentialsSafeHandle ToNativeCredentials()
+ {
+ return null;
+ }
+ }
}
/// <summary>
/// Client-side SSL credentials.
/// </summary>
- public class SslCredentials : Credentials
+ public sealed class SslCredentials : Credentials
{
- string pemRootCerts;
+ readonly string rootCertificates;
+ readonly KeyCertificatePair keyCertificatePair;
- public SslCredentials(string pemRootCerts)
+ /// <summary>
+ /// Creates client-side SSL credentials loaded from
+ /// disk file pointed to by the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable.
+ /// If that fails, gets the roots certificates from a well known place on disk.
+ /// </summary>
+ public SslCredentials() : this(null, null)
{
- this.pemRootCerts = pemRootCerts;
+ }
+
+ /// <summary>
+ /// Creates client-side SSL credentials from
+ /// a string containing PEM encoded root certificates.
+ /// </summary>
+ public SslCredentials(string rootCertificates) : this(rootCertificates, null)
+ {
+ }
+
+ /// <summary>
+ /// Creates client-side SSL credentials.
+ /// </summary>
+ /// <param name="rootCertificates">string containing PEM encoded server root certificates.</param>
+ /// <param name="keyCertificatePair">a key certificate pair.</param>
+ public SslCredentials(string rootCertificates, KeyCertificatePair keyCertificatePair)
+ {
+ this.rootCertificates = rootCertificates;
+ this.keyCertificatePair = keyCertificatePair;
}
/// <summary>
/// PEM encoding of the server root certificates.
/// </summary>
- public string RootCerts
+ public string RootCertificates
+ {
+ get
+ {
+ return this.rootCertificates;
+ }
+ }
+
+ /// <summary>
+ /// Client side key and certificate pair.
+ /// If null, client will not use key and certificate pair.
+ /// </summary>
+ public KeyCertificatePair KeyCertificatePair
{
get
{
- return this.pemRootCerts;
+ return this.keyCertificatePair;
}
}
internal override CredentialsSafeHandle ToNativeCredentials()
{
- return CredentialsSafeHandle.CreateSslCredentials(pemRootCerts);
+ return CredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair);
}
}
}
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index fd68b91851..0d879e9b1e 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -47,7 +47,6 @@
<Compile Include="IServerStreamWriter.cs" />
<Compile Include="IAsyncStreamWriter.cs" />
<Compile Include="IAsyncStreamReader.cs" />
- <Compile Include="Internal\GrpcLog.cs" />
<Compile Include="Version.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="RpcException.cs" />
@@ -103,6 +102,11 @@
<Compile Include="ChannelOptions.cs" />
<Compile Include="AsyncUnaryCall.cs" />
<Compile Include="VersionInfo.cs" />
+ <Compile Include="Internal\CStringSafeHandle.cs" />
+ <Compile Include="KeyCertificatePair.cs" />
+ <Compile Include="Logging\ILogger.cs" />
+ <Compile Include="Logging\ConsoleLogger.cs" />
+ <Compile Include="Internal\NativeLogRedirector.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Grpc.Core.nuspec" />
@@ -133,4 +137,7 @@
</Target>
<Import Project="..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\packages\grpc.dependencies.openssl.redist.1.0.2.2\build\portable-net45\grpc.dependencies.openssl.redist.targets')" />
<Import Project="..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\portable-net45\grpc.dependencies.zlib.redist.targets')" />
+ <ItemGroup>
+ <Folder Include="Logging\" />
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 47d1651aab..034a66be3c 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -35,6 +35,7 @@ using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Grpc.Core.Internal;
+using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core
@@ -55,6 +56,8 @@ namespace Grpc.Core
static object staticLock = new object();
static GrpcEnvironment instance;
+ static ILogger logger = new ConsoleLogger();
+
readonly GrpcThreadPool threadPool;
readonly CompletionRegistry completionRegistry;
readonly DebugStats debugStats = new DebugStats();
@@ -93,17 +96,38 @@ namespace Grpc.Core
}
/// <summary>
+ /// Gets application-wide logger used by gRPC.
+ /// </summary>
+ /// <value>The logger.</value>
+ public static ILogger Logger
+ {
+ get
+ {
+ return logger;
+ }
+ }
+
+ /// <summary>
+ /// Sets the application-wide logger that should be used by gRPC.
+ /// </summary>
+ public static void SetLogger(ILogger customLogger)
+ {
+ Preconditions.CheckNotNull(customLogger);
+ logger = customLogger;
+ }
+
+ /// <summary>
/// Creates gRPC environment.
/// </summary>
private GrpcEnvironment()
{
- GrpcLog.RedirectNativeLogs(Console.Error);
+ NativeLogRedirector.Redirect();
grpcsharp_init();
completionRegistry = new CompletionRegistry(this);
threadPool = new GrpcThreadPool(this, THREAD_POOL_SIZE);
threadPool.Start();
// TODO: use proper logging here
- Console.WriteLine("GRPC initialized.");
+ Logger.Info("gRPC initialized.");
}
/// <summary>
@@ -154,8 +178,7 @@ namespace Grpc.Core
debugStats.CheckOK();
- // TODO: use proper logging here
- Console.WriteLine("GRPC shutdown.");
+ Logger.Info("gRPC shutdown.");
}
/// <summary>
@@ -171,7 +194,7 @@ namespace Grpc.Core
}
catch (Exception e)
{
- Console.WriteLine("Error occured while shutting down GrpcEnvironment: " + e);
+ Logger.Error(e, "Error occured while shutting down GrpcEnvironment.");
}
});
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index f983dbb759..bfcb9366a1 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -38,6 +38,7 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core.Internal;
+using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
@@ -47,6 +48,8 @@ namespace Grpc.Core.Internal
/// </summary>
internal class AsyncCall<TRequest, TResponse> : AsyncCallBase<TRequest, TResponse>
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCall<TRequest, TResponse>>();
+
Channel channel;
// Completion of a pending unary response if not null.
@@ -61,10 +64,10 @@ namespace Grpc.Core.Internal
{
}
- public void Initialize(Channel channel, CompletionQueueSafeHandle cq, string methodName)
+ public void Initialize(Channel channel, CompletionQueueSafeHandle cq, string methodName, Timespec deadline)
{
this.channel = channel;
- var call = CallSafeHandle.Create(channel.Handle, channel.CompletionRegistry, cq, methodName, channel.Target, Timespec.InfFuture);
+ var call = channel.Handle.CreateCall(channel.CompletionRegistry, cq, methodName, channel.Target, deadline);
channel.Environment.DebugStats.ActiveClientCalls.Increment();
InitializeInternal(call);
}
@@ -76,7 +79,7 @@ namespace Grpc.Core.Internal
/// <summary>
/// Blocking unary request - unary response call.
/// </summary>
- public TResponse UnaryCall(Channel channel, string methodName, TRequest msg, Metadata headers)
+ public TResponse UnaryCall(Channel channel, string methodName, TRequest msg, Metadata headers, DateTime deadline)
{
using (CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create())
{
@@ -86,7 +89,7 @@ namespace Grpc.Core.Internal
lock (myLock)
{
- Initialize(channel, cq, methodName);
+ Initialize(channel, cq, methodName, Timespec.FromDateTime(deadline));
started = true;
halfcloseRequested = true;
readingDone = true;
@@ -106,7 +109,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured while invoking completion delegate: " + e);
+ Logger.Error(e, "Exception occured while invoking completion delegate.");
}
}
}
@@ -126,7 +129,7 @@ namespace Grpc.Core.Internal
/// <summary>
/// Starts a unary request - unary response call.
/// </summary>
- public Task<TResponse> UnaryCallAsync(TRequest msg, Metadata headers)
+ public Task<TResponse> UnaryCallAsync(TRequest msg, Metadata headers, DateTime deadline)
{
lock (myLock)
{
@@ -151,7 +154,7 @@ namespace Grpc.Core.Internal
/// Starts a streamed request - unary response call.
/// Use StartSendMessage and StartSendCloseFromClient to stream requests.
/// </summary>
- public Task<TResponse> ClientStreamingCallAsync(Metadata headers)
+ public Task<TResponse> ClientStreamingCallAsync(Metadata headers, DateTime deadline)
{
lock (myLock)
{
@@ -173,7 +176,7 @@ namespace Grpc.Core.Internal
/// <summary>
/// Starts a unary request - streamed response call.
/// </summary>
- public void StartServerStreamingCall(TRequest msg, Metadata headers)
+ public void StartServerStreamingCall(TRequest msg, Metadata headers, DateTime deadline)
{
lock (myLock)
{
@@ -196,7 +199,7 @@ namespace Grpc.Core.Internal
/// Starts a streaming request - streaming response call.
/// Use StartSendMessage and StartSendCloseFromClient to stream requests.
/// </summary>
- public void StartDuplexStreamingCall(Metadata headers)
+ public void StartDuplexStreamingCall(Metadata headers, DateTime deadline)
{
lock (myLock)
{
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 64713c8c52..38f2a5baeb 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -38,6 +38,7 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core.Internal;
+using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
@@ -48,6 +49,8 @@ namespace Grpc.Core.Internal
/// </summary>
internal abstract class AsyncCallBase<TWrite, TRead>
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCallBase<TWrite, TRead>>();
+
readonly Func<TWrite, byte[]> serializer;
readonly Func<byte[], TRead> deserializer;
@@ -233,9 +236,9 @@ namespace Grpc.Core.Internal
payload = serializer(msg);
return true;
}
- catch (Exception)
+ catch (Exception e)
{
- Console.WriteLine("Exception occured while trying to serialize message");
+ Logger.Error(e, "Exception occured while trying to serialize message");
payload = null;
return false;
}
@@ -248,9 +251,9 @@ namespace Grpc.Core.Internal
msg = deserializer(payload);
return true;
}
- catch (Exception)
+ catch (Exception e)
{
- Console.WriteLine("Exception occured while trying to deserialize message");
+ Logger.Error(e, "Exception occured while trying to deserialize message.");
msg = default(TRead);
return false;
}
@@ -264,7 +267,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured while invoking completion delegate: " + e);
+ Logger.Error(e, "Exception occured while invoking completion delegate.");
}
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index f809f4a84c..513902ee36 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -48,6 +48,7 @@ namespace Grpc.Core.Internal
internal class AsyncCallServer<TRequest, TResponse> : AsyncCallBase<TResponse, TRequest>
{
readonly TaskCompletionSource<object> finishedServersideTcs = new TaskCompletionSource<object>();
+ readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
readonly GrpcEnvironment environment;
public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, GrpcEnvironment environment) : base(serializer, deserializer)
@@ -118,6 +119,26 @@ namespace Grpc.Core.Internal
}
}
+ /// <summary>
+ /// Gets cancellation token that gets cancelled once close completion
+ /// is received and the cancelled flag is set.
+ /// </summary>
+ public CancellationToken CancellationToken
+ {
+ get
+ {
+ return cancellationTokenSource.Token;
+ }
+ }
+
+ public string Peer
+ {
+ get
+ {
+ return call.GetPeer();
+ }
+ }
+
protected override void OnReleaseResources()
{
environment.DebugStats.ActiveServerCalls.Decrement();
@@ -138,6 +159,8 @@ namespace Grpc.Core.Internal
{
// Once we cancel, we don't have to care that much
// about reads and writes.
+
+ // TODO(jtattermusch): is this still necessary?
Cancel();
}
@@ -145,6 +168,11 @@ namespace Grpc.Core.Internal
}
// TODO(jtattermusch): handle error
+ if (cancelled)
+ {
+ cancellationTokenSource.Cancel();
+ }
+
finishedServersideTcs.SetResult(null);
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
new file mode 100644
index 0000000000..92fbe8cf0f
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
@@ -0,0 +1,60 @@
+#region Copyright notice and license
+// 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.
+#endregion
+using System;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Owned char* object.
+ /// </summary>
+ internal class CStringSafeHandle : SafeHandleZeroIsInvalid
+ {
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern void gprsharp_free(IntPtr ptr);
+
+ private CStringSafeHandle()
+ {
+ }
+
+ public string GetValue()
+ {
+ return Marshal.PtrToStringAnsi(handle);
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ gprsharp_free(handle);
+ return true;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 19dbb83f24..714749b171 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -46,9 +46,6 @@ namespace Grpc.Core.Internal
CompletionRegistry completionRegistry;
[DllImport("grpc_csharp_ext.dll")]
- static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
-
- [DllImport("grpc_csharp_ext.dll")]
static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
[DllImport("grpc_csharp_ext.dll")]
@@ -92,19 +89,15 @@ namespace Grpc.Core.Internal
BatchContextSafeHandle ctx);
[DllImport("grpc_csharp_ext.dll")]
+ static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call);
+
+ [DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_call_destroy(IntPtr call);
private CallSafeHandle()
{
}
- public static CallSafeHandle Create(ChannelSafeHandle channel, CompletionRegistry registry, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)
- {
- var result = grpcsharp_channel_create_call(channel, cq, method, host, deadline);
- result.SetCompletionRegistry(registry);
- return result;
- }
-
public void SetCompletionRegistry(CompletionRegistry completionRegistry)
{
this.completionRegistry = completionRegistry;
@@ -190,6 +183,14 @@ namespace Grpc.Core.Internal
grpcsharp_call_cancel_with_status(this, status.StatusCode, status.Detail).CheckOk();
}
+ public string GetPeer()
+ {
+ using (var cstring = grpcsharp_call_get_peer(this))
+ {
+ return cstring.GetValue();
+ }
+ }
+
protected override bool ReleaseHandle()
{
grpcsharp_call_destroy(handle);
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index f046f4c6d0..20815efbd3 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -41,21 +41,24 @@ namespace Grpc.Core.Internal
internal class ChannelSafeHandle : SafeHandleZeroIsInvalid
{
[DllImport("grpc_csharp_ext.dll")]
- static extern ChannelSafeHandle grpcsharp_channel_create(string target, ChannelArgsSafeHandle channelArgs);
+ static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs);
[DllImport("grpc_csharp_ext.dll")]
static extern ChannelSafeHandle grpcsharp_secure_channel_create(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
[DllImport("grpc_csharp_ext.dll")]
+ static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
+
+ [DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_channel_destroy(IntPtr channel);
private ChannelSafeHandle()
{
}
- public static ChannelSafeHandle Create(string target, ChannelArgsSafeHandle channelArgs)
+ public static ChannelSafeHandle CreateInsecure(string target, ChannelArgsSafeHandle channelArgs)
{
- return grpcsharp_channel_create(target, channelArgs);
+ return grpcsharp_insecure_channel_create(target, channelArgs);
}
public static ChannelSafeHandle CreateSecure(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
@@ -63,6 +66,13 @@ namespace Grpc.Core.Internal
return grpcsharp_secure_channel_create(credentials, target, channelArgs);
}
+ public CallSafeHandle CreateCall(CompletionRegistry registry, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline)
+ {
+ var result = grpcsharp_channel_create_call(this, cq, method, host, deadline);
+ result.SetCompletionRegistry(registry);
+ return result;
+ }
+
protected override bool ReleaseHandle()
{
grpcsharp_channel_destroy(handle);
diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
index f6d8aa0600..2796c959a3 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
@@ -35,6 +35,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.InteropServices;
+using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
@@ -45,6 +46,8 @@ namespace Grpc.Core.Internal
internal class CompletionRegistry
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<CompletionRegistry>();
+
readonly GrpcEnvironment environment;
readonly ConcurrentDictionary<IntPtr, OpCompletionDelegate> dict = new ConcurrentDictionary<IntPtr, OpCompletionDelegate>();
@@ -81,7 +84,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured while invoking completion delegate: " + e);
+ Logger.Error(e, "Exception occured while invoking completion delegate.");
}
finally
{
diff --git a/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
index f361199068..8b4fa85e5d 100644
--- a/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
@@ -50,9 +50,23 @@ namespace Grpc.Core.Internal
{
}
- public static CredentialsSafeHandle CreateSslCredentials(string pemRootCerts)
+ public static CredentialsSafeHandle CreateNullCredentials()
{
- return grpcsharp_ssl_credentials_create(pemRootCerts, null, null);
+ var creds = new CredentialsSafeHandle();
+ creds.SetHandle(IntPtr.Zero);
+ return creds;
+ }
+
+ public static CredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair)
+ {
+ if (keyCertPair != null)
+ {
+ return grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey);
+ }
+ else
+ {
+ return grpcsharp_ssl_credentials_create(pemRootCerts, null, null);
+ }
}
protected override bool ReleaseHandle()
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index b77e893044..cb4c7c821e 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -36,7 +36,7 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
-using Grpc.Core.Internal;
+using Grpc.Core.Logging;
namespace Grpc.Core.Internal
{
@@ -45,6 +45,8 @@ namespace Grpc.Core.Internal
/// </summary>
internal class GrpcThreadPool
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<GrpcThreadPool>();
+
readonly GrpcEnvironment environment;
readonly object myLock = new object();
readonly List<Thread> threads = new List<Thread>();
@@ -82,7 +84,7 @@ namespace Grpc.Core.Internal
{
cq.Shutdown();
- Console.WriteLine("Waiting for GRPC threads to finish.");
+ Logger.Info("Waiting for GRPC threads to finish.");
foreach (var thread in threads)
{
thread.Join();
@@ -129,12 +131,12 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured while invoking completion delegate: " + e);
+ Logger.Error(e, "Exception occured while invoking completion delegate");
}
}
}
while (ev.type != GRPCCompletionType.Shutdown);
- Console.WriteLine("Completion queue has shutdown successfully, thread " + Thread.CurrentThread.Name + " exiting.");
+ Logger.Info("Completion queue has shutdown successfully, thread {0} exiting.", Thread.CurrentThread.Name);
}
}
}
diff --git a/src/csharp/Grpc.Core/Internal/GrpcLog.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
index 2f3c8ad71c..b8a55c5fe8 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcLog.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
@@ -44,30 +44,26 @@ namespace Grpc.Core.Internal
/// <summary>
/// Logs from gRPC C core library can get lost if your application is not a console app.
- /// This class allows redirection of logs to arbitrary destination.
+ /// This class allows redirection of logs to gRPC logger.
/// </summary>
- internal static class GrpcLog
+ internal static class NativeLogRedirector
{
static object staticLock = new object();
static GprLogDelegate writeCallback;
- static TextWriter dest;
[DllImport("grpc_csharp_ext.dll")]
static extern void grpcsharp_redirect_log(GprLogDelegate callback);
/// <summary>
- /// Sets text writer as destination for logs from native gRPC C core library.
- /// Only first invocation has effect.
+ /// Redirects logs from native gRPC C core library to a general logger.
/// </summary>
- /// <param name="textWriter"></param>
- public static void RedirectNativeLogs(TextWriter textWriter)
+ public static void Redirect()
{
lock (staticLock)
{
if (writeCallback == null)
{
writeCallback = new GprLogDelegate(HandleWrite);
- dest = textWriter;
grpcsharp_redirect_log(writeCallback);
}
}
@@ -77,13 +73,30 @@ namespace Grpc.Core.Internal
{
try
{
- // TODO: DateTime format used here is different than in C core.
- dest.WriteLine(string.Format("{0}{1} {2} {3}:{4}: {5}",
- Marshal.PtrToStringAnsi(severityStringPtr), DateTime.Now,
+ var logger = GrpcEnvironment.Logger;
+ string severityString = Marshal.PtrToStringAnsi(severityStringPtr);
+ string message = string.Format("{0} {1}:{2}: {3}",
threadId,
Marshal.PtrToStringAnsi(fileStringPtr),
line,
- Marshal.PtrToStringAnsi(msgPtr)));
+ Marshal.PtrToStringAnsi(msgPtr));
+
+ switch (severityString)
+ {
+ case "D":
+ logger.Debug(message);
+ break;
+ case "I":
+ logger.Info(message);
+ break;
+ case "E":
+ logger.Error(message);
+ break;
+ default:
+ // severity not recognized, default to error.
+ logger.Error(message);
+ break;
+ }
}
catch (Exception e)
{
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 3680b1e791..19f0e3c57f 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -37,6 +37,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Grpc.Core.Internal;
+using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core.Internal
@@ -50,6 +51,8 @@ namespace Grpc.Core.Internal
where TRequest : class
where TResponse : class
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<UnaryServerCallHandler<TRequest, TResponse>>();
+
readonly Method<TRequest, TResponse> method;
readonly UnaryServerMethod<TRequest, TResponse> handler;
@@ -72,7 +75,7 @@ namespace Grpc.Core.Internal
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
- var context = HandlerUtils.NewContext(newRpc);
+ var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, asyncCall.CancellationToken);
try
{
Preconditions.CheckArgument(await requestStream.MoveNext());
@@ -85,7 +88,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured in handler: " + e);
+ Logger.Error(e, "Exception occured in handler.");
status = HandlerUtils.StatusFromException(e);
}
try
@@ -104,6 +107,8 @@ namespace Grpc.Core.Internal
where TRequest : class
where TResponse : class
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<ServerStreamingServerCallHandler<TRequest, TResponse>>();
+
readonly Method<TRequest, TResponse> method;
readonly ServerStreamingServerMethod<TRequest, TResponse> handler;
@@ -126,7 +131,7 @@ namespace Grpc.Core.Internal
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
- var context = HandlerUtils.NewContext(newRpc);
+ var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, asyncCall.CancellationToken);
try
{
Preconditions.CheckArgument(await requestStream.MoveNext());
@@ -138,7 +143,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured in handler: " + e);
+ Logger.Error(e, "Exception occured in handler.");
status = HandlerUtils.StatusFromException(e);
}
@@ -158,6 +163,8 @@ namespace Grpc.Core.Internal
where TRequest : class
where TResponse : class
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<ClientStreamingServerCallHandler<TRequest, TResponse>>();
+
readonly Method<TRequest, TResponse> method;
readonly ClientStreamingServerMethod<TRequest, TResponse> handler;
@@ -180,7 +187,7 @@ namespace Grpc.Core.Internal
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
- var context = HandlerUtils.NewContext(newRpc);
+ var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, asyncCall.CancellationToken);
try
{
var result = await handler(requestStream, context);
@@ -196,7 +203,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured in handler: " + e);
+ Logger.Error(e, "Exception occured in handler.");
status = HandlerUtils.StatusFromException(e);
}
@@ -216,6 +223,8 @@ namespace Grpc.Core.Internal
where TRequest : class
where TResponse : class
{
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<DuplexStreamingServerCallHandler<TRequest, TResponse>>();
+
readonly Method<TRequest, TResponse> method;
readonly DuplexStreamingServerMethod<TRequest, TResponse> handler;
@@ -238,7 +247,7 @@ namespace Grpc.Core.Internal
var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
Status status;
- var context = HandlerUtils.NewContext(newRpc);
+ var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, asyncCall.CancellationToken);
try
{
await handler(requestStream, responseStream, context);
@@ -246,7 +255,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- Console.WriteLine("Exception occured in handler: " + e);
+ Logger.Error(e, "Exception occured in handler.");
status = HandlerUtils.StatusFromException(e);
}
try
@@ -295,11 +304,13 @@ namespace Grpc.Core.Internal
return new Status(StatusCode.Unknown, "Exception was thrown by handler.");
}
- public static ServerCallContext NewContext(ServerRpcNew newRpc)
+ public static ServerCallContext NewContext(ServerRpcNew newRpc, string peer, CancellationToken cancellationToken)
{
+ DateTime realtimeDeadline = newRpc.Deadline.ToClockType(GPRClockType.Realtime).ToDateTime();
+
return new ServerCallContext(
- newRpc.Method, newRpc.Host, newRpc.Deadline.ToDateTime(),
- newRpc.RequestMetadata, CancellationToken.None);
+ newRpc.Method, newRpc.Host, peer, realtimeDeadline,
+ newRpc.RequestMetadata, cancellationToken);
}
}
}
diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
index 961180741a..59238a452c 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
@@ -51,10 +51,10 @@ namespace Grpc.Core.Internal
{
}
- public static ServerCredentialsSafeHandle CreateSslCredentials(string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray)
+ public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray)
{
Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
- return grpcsharp_ssl_server_credentials_create(null,
+ return grpcsharp_ssl_server_credentials_create(pemRootCerts,
keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
new UIntPtr((ulong)keyCertPairCertChainArray.Length));
}
diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
index 9e1170e6dd..f9b44b1acf 100644
--- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
@@ -48,7 +48,7 @@ namespace Grpc.Core.Internal
static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
[DllImport("grpc_csharp_ext.dll")]
- static extern int grpcsharp_server_add_http2_port(ServerSafeHandle server, string addr);
+ static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr);
[DllImport("grpc_csharp_ext.dll")]
static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
@@ -77,12 +77,12 @@ namespace Grpc.Core.Internal
return grpcsharp_server_create(cq, args);
}
- public int AddListeningPort(string addr)
+ public int AddInsecurePort(string addr)
{
- return grpcsharp_server_add_http2_port(this, addr);
+ return grpcsharp_server_add_insecure_http2_port(this, addr);
}
- public int AddListeningPort(string addr, ServerCredentialsSafeHandle credentials)
+ public int AddSecurePort(string addr, ServerCredentialsSafeHandle credentials)
{
return grpcsharp_server_add_secure_http2_port(this, addr, credentials);
}
diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs
index da2819f14d..e83d21f4a4 100644
--- a/src/csharp/Grpc.Core/Internal/Timespec.cs
+++ b/src/csharp/Grpc.Core/Internal/Timespec.cs
@@ -32,6 +32,8 @@ using System;
using System.Runtime.InteropServices;
using System.Threading;
+using Grpc.Core.Utils;
+
namespace Grpc.Core.Internal
{
/// <summary>
@@ -40,32 +42,43 @@ namespace Grpc.Core.Internal
[StructLayout(LayoutKind.Sequential)]
internal struct Timespec
{
- const int NanosPerSecond = 1000 * 1000 * 1000;
- const int NanosPerTick = 100;
+ const long NanosPerSecond = 1000 * 1000 * 1000;
+ const long NanosPerTick = 100;
+ const long TicksPerSecond = NanosPerSecond / NanosPerTick;
static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
[DllImport("grpc_csharp_ext.dll")]
- static extern Timespec gprsharp_now();
+ static extern Timespec gprsharp_now(GPRClockType clockType);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern Timespec gprsharp_inf_future(GPRClockType clockType);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ static extern Timespec gprsharp_inf_past(GPRClockType clockType);
[DllImport("grpc_csharp_ext.dll")]
- static extern Timespec gprsharp_inf_future();
+ static extern Timespec gprsharp_convert_clock_type(Timespec t, GPRClockType targetClock);
[DllImport("grpc_csharp_ext.dll")]
static extern int gprsharp_sizeof_timespec();
- public Timespec(IntPtr tv_sec, int tv_nsec)
+ public Timespec(IntPtr tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime)
+ {
+ }
+
+ public Timespec(IntPtr tv_sec, int tv_nsec, GPRClockType clock_type)
{
this.tv_sec = tv_sec;
this.tv_nsec = tv_nsec;
- this.clock_type = GPRClockType.Realtime;
+ this.clock_type = clock_type;
}
// NOTE: on linux 64bit sizeof(gpr_timespec) = 16, on windows 32bit sizeof(gpr_timespec) = 8
// so IntPtr seems to have the right size to work on both.
- public System.IntPtr tv_sec;
- public int tv_nsec;
- public GPRClockType clock_type;
+ private System.IntPtr tv_sec;
+ private int tv_nsec;
+ private GPRClockType clock_type;
/// <summary>
/// Timespec a long time in the future.
@@ -74,54 +87,164 @@ namespace Grpc.Core.Internal
{
get
{
- return gprsharp_inf_future();
+ return gprsharp_inf_future(GPRClockType.Realtime);
+ }
+ }
+
+ /// <summary>
+ /// Timespec a long time in the past.
+ /// </summary>
+ public static Timespec InfPast
+ {
+ get
+ {
+ return gprsharp_inf_past(GPRClockType.Realtime);
}
}
+ /// <summary>
+ /// Return Timespec representing the current time.
+ /// </summary>
public static Timespec Now
{
get
{
- return gprsharp_now();
+ return gprsharp_now(GPRClockType.Realtime);
}
}
-
- public DateTime ToDateTime()
+
+ /// <summary>
+ /// Seconds since unix epoch.
+ /// </summary>
+ public IntPtr TimevalSeconds
{
- return UnixEpoch.AddTicks(tv_sec.ToInt64() * (NanosPerSecond / NanosPerTick) + tv_nsec / NanosPerTick);
+ get
+ {
+ return tv_sec;
+ }
}
- internal static int NativeSize
+ /// <summary>
+ /// The nanoseconds part of timeval.
+ /// </summary>
+ public int TimevalNanos
{
get
{
- return gprsharp_sizeof_timespec();
+ return tv_nsec;
}
}
/// <summary>
- /// Creates a GPR deadline from current instant and given timeout.
+ /// Converts the timespec to desired clock type.
/// </summary>
- /// <returns>The from timeout.</returns>
- public static Timespec DeadlineFromTimeout(TimeSpan timeout)
+ public Timespec ToClockType(GPRClockType targetClock)
+ {
+ return gprsharp_convert_clock_type(this, targetClock);
+ }
+
+ /// <summary>
+ /// Converts Timespec to DateTime.
+ /// Timespec needs to be of type GPRClockType.Realtime and needs to represent a legal value.
+ /// DateTime has lower resolution (100ns), so rounding can occurs.
+ /// Value are always rounded up to the nearest DateTime value in the future.
+ ///
+ /// For Timespec.InfFuture or if timespec is after the largest representable DateTime, DateTime.MaxValue is returned.
+ /// For Timespec.InfPast or if timespec is before the lowest representable DateTime, DateTime.MinValue is returned.
+ ///
+ /// Unless DateTime.MaxValue or DateTime.MinValue is returned, the resulting DateTime is always in UTC
+ /// (DateTimeKind.Utc)
+ /// </summary>
+ public DateTime ToDateTime()
{
- if (timeout == Timeout.InfiniteTimeSpan)
+ Preconditions.CheckState(tv_nsec >= 0 && tv_nsec < NanosPerSecond);
+ Preconditions.CheckState(clock_type == GPRClockType.Realtime);
+
+ // fast path for InfFuture
+ if (this.Equals(InfFuture))
+ {
+ return DateTime.MaxValue;
+ }
+
+ // fast path for InfPast
+ if (this.Equals(InfPast))
+ {
+ return DateTime.MinValue;
+ }
+
+ try
+ {
+ // convert nanos to ticks, round up to the nearest tick
+ long ticksFromNanos = tv_nsec / NanosPerTick + ((tv_nsec % NanosPerTick != 0) ? 1 : 0);
+ long ticksTotal = checked(tv_sec.ToInt64() * TicksPerSecond + ticksFromNanos);
+ return UnixEpoch.AddTicks(ticksTotal);
+ }
+ catch (OverflowException)
+ {
+ // ticks out of long range
+ return tv_sec.ToInt64() > 0 ? DateTime.MaxValue : DateTime.MinValue;
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ // resulting date time would be larger than MaxValue
+ return tv_sec.ToInt64() > 0 ? DateTime.MaxValue : DateTime.MinValue;
+ }
+ }
+
+ /// <summary>
+ /// Creates DateTime to Timespec.
+ /// DateTime has to be in UTC (DateTimeKind.Utc) unless it's DateTime.MaxValue or DateTime.MinValue.
+ /// For DateTime.MaxValue of date time after the largest representable Timespec, Timespec.InfFuture is returned.
+ /// For DateTime.MinValue of date time before the lowest representable Timespec, Timespec.InfPast is returned.
+ /// </summary>
+ /// <returns>The date time.</returns>
+ /// <param name="dateTime">Date time.</param>
+ public static Timespec FromDateTime(DateTime dateTime)
+ {
+ if (dateTime == DateTime.MaxValue)
{
return Timespec.InfFuture;
}
- return Timespec.Now.Add(timeout);
+
+ if (dateTime == DateTime.MinValue)
+ {
+ return Timespec.InfPast;
+ }
+
+ Preconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime");
+
+ try
+ {
+ TimeSpan timeSpan = dateTime - UnixEpoch;
+ long ticks = timeSpan.Ticks;
+
+ long seconds = ticks / TicksPerSecond;
+ int nanos = (int)((ticks % TicksPerSecond) * NanosPerTick);
+ if (nanos < 0)
+ {
+ // correct the result based on C# modulo semantics for negative dividend
+ seconds--;
+ nanos += (int)NanosPerSecond;
+ }
+ // new IntPtr possibly throws OverflowException
+ return new Timespec(new IntPtr(seconds), nanos);
+ }
+ catch (OverflowException)
+ {
+ return dateTime > UnixEpoch ? Timespec.InfFuture : Timespec.InfPast;
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ return dateTime > UnixEpoch ? Timespec.InfFuture : Timespec.InfPast;
+ }
}
- public Timespec Add(TimeSpan timeSpan)
+ internal static int NativeSize
{
- long nanos = (long)tv_nsec + (timeSpan.Ticks % TimeSpan.TicksPerSecond) * NanosPerTick;
- long overflow_sec = (nanos > NanosPerSecond) ? 1 : 0;
-
- Timespec result;
- result.tv_nsec = (int)(nanos % NanosPerSecond);
- result.tv_sec = new IntPtr(tv_sec.ToInt64() + (timeSpan.Ticks / TimeSpan.TicksPerSecond) + overflow_sec);
- result.clock_type = GPRClockType.Realtime;
- return result;
+ get
+ {
+ return gprsharp_sizeof_timespec();
+ }
}
}
}
diff --git a/src/csharp/Grpc.Core/KeyCertificatePair.cs b/src/csharp/Grpc.Core/KeyCertificatePair.cs
new file mode 100644
index 0000000000..7cea18618e
--- /dev/null
+++ b/src/csharp/Grpc.Core/KeyCertificatePair.cs
@@ -0,0 +1,84 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Key certificate pair (in PEM encoding).
+ /// </summary>
+ public sealed class KeyCertificatePair
+ {
+ readonly string certificateChain;
+ readonly string privateKey;
+
+ /// <summary>
+ /// Creates a new certificate chain - private key pair.
+ /// </summary>
+ /// <param name="certificateChain">PEM encoded certificate chain.</param>
+ /// <param name="privateKey">PEM encoded private key.</param>
+ public KeyCertificatePair(string certificateChain, string privateKey)
+ {
+ this.certificateChain = Preconditions.CheckNotNull(certificateChain);
+ this.privateKey = Preconditions.CheckNotNull(privateKey);
+ }
+
+ /// <summary>
+ /// PEM encoded certificate chain.
+ /// </summary>
+ public string CertificateChain
+ {
+ get
+ {
+ return certificateChain;
+ }
+ }
+
+ /// <summary>
+ /// PEM encoded private key.
+ /// </summary>
+ public string PrivateKey
+ {
+ get
+ {
+ return privateKey;
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
new file mode 100644
index 0000000000..c67765c78d
--- /dev/null
+++ b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
@@ -0,0 +1,103 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Grpc.Core.Logging
+{
+ /// <summary>Logger that logs to System.Console.</summary>
+ public class ConsoleLogger : ILogger
+ {
+ readonly Type forType;
+ readonly string forTypeString;
+
+ public ConsoleLogger() : this(null)
+ {
+ }
+
+ private ConsoleLogger(Type forType)
+ {
+ this.forType = forType;
+ this.forTypeString = forType != null ? forType.FullName + " " : "";
+ }
+
+ public ILogger ForType<T>()
+ {
+ if (typeof(T) == forType)
+ {
+ return this;
+ }
+ return new ConsoleLogger(typeof(T));
+ }
+
+ public void Debug(string message, params object[] formatArgs)
+ {
+ Log("D", message, formatArgs);
+ }
+
+ public void Info(string message, params object[] formatArgs)
+ {
+ Log("I", message, formatArgs);
+ }
+
+ public void Warning(string message, params object[] formatArgs)
+ {
+ Log("W", message, formatArgs);
+ }
+
+ public void Warning(Exception exception, string message, params object[] formatArgs)
+ {
+ Log("W", message + " " + exception, formatArgs);
+ }
+
+ public void Error(string message, params object[] formatArgs)
+ {
+ Log("E", message, formatArgs);
+ }
+
+ public void Error(Exception exception, string message, params object[] formatArgs)
+ {
+ Log("E", message + " " + exception, formatArgs);
+ }
+
+ private void Log(string severityString, string message, object[] formatArgs)
+ {
+ Console.Error.WriteLine("{0}{1} {2}{3}",
+ severityString,
+ DateTime.Now,
+ forTypeString,
+ string.Format(message, formatArgs));
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Logging/ILogger.cs b/src/csharp/Grpc.Core/Logging/ILogger.cs
new file mode 100644
index 0000000000..0d58f133e3
--- /dev/null
+++ b/src/csharp/Grpc.Core/Logging/ILogger.cs
@@ -0,0 +1,57 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace Grpc.Core.Logging
+{
+ /// <summary>For logging messages.</summary>
+ public interface ILogger
+ {
+ /// <summary>Returns a logger associated with the specified type.</summary>
+ ILogger ForType<T>();
+
+ void Debug(string message, params object[] formatArgs);
+
+ void Info(string message, params object[] formatArgs);
+
+ void Warning(string message, params object[] formatArgs);
+
+ void Warning(Exception exception, string message, params object[] formatArgs);
+
+ void Error(string message, params object[] formatArgs);
+
+ void Error(Exception exception, string message, params object[] formatArgs);
+ }
+}
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index fd30735359..3217547cc4 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -38,6 +38,7 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Grpc.Core.Internal;
+using Grpc.Core.Logging;
using Grpc.Core.Utils;
namespace Grpc.Core
@@ -52,6 +53,8 @@ namespace Grpc.Core
/// </summary>
public const int PickUnusedPort = 0;
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<Server>();
+
readonly GrpcEnvironment environment;
readonly List<ChannelOption> options;
readonly ServerSafeHandle handle;
@@ -95,28 +98,31 @@ namespace Grpc.Core
}
/// <summary>
- /// Add a non-secure port on which server should listen.
+ /// Add a port on which server should listen.
/// Only call this before Start().
/// </summary>
/// <returns>The port on which server will be listening.</returns>
/// <param name="host">the host</param>
/// <param name="port">the port. If zero, an unused port is chosen automatically.</param>
- public int AddListeningPort(string host, int port)
+ public int AddPort(string host, int port, ServerCredentials credentials)
{
- return AddListeningPortInternal(host, port, null);
- }
-
- /// <summary>
- /// Add a non-secure port on which server should listen.
- /// Only call this before Start().
- /// </summary>
- /// <returns>The port on which server will be listening.</returns>
- /// <param name="host">the host</param>
- /// <param name="port">the port. If zero, an unused port is chosen automatically.</param>
- public int AddListeningPort(string host, int port, ServerCredentials credentials)
- {
- Preconditions.CheckNotNull(credentials);
- return AddListeningPortInternal(host, port, credentials);
+ lock (myLock)
+ {
+ Preconditions.CheckNotNull(credentials);
+ Preconditions.CheckState(!startRequested);
+ var address = string.Format("{0}:{1}", host, port);
+ using (var nativeCredentials = credentials.ToNativeCredentials())
+ {
+ if (nativeCredentials != null)
+ {
+ return handle.AddSecurePort(address, nativeCredentials);
+ }
+ else
+ {
+ return handle.AddInsecurePort(address);
+ }
+ }
+ }
}
/// <summary>
@@ -183,26 +189,6 @@ namespace Grpc.Core
handle.Dispose();
}
- private int AddListeningPortInternal(string host, int port, ServerCredentials credentials)
- {
- lock (myLock)
- {
- Preconditions.CheckState(!startRequested);
- var address = string.Format("{0}:{1}", host, port);
- if (credentials != null)
- {
- using (var nativeCredentials = credentials.ToNativeCredentials())
- {
- return handle.AddListeningPort(address, nativeCredentials);
- }
- }
- else
- {
- return handle.AddListeningPort(address);
- }
- }
- }
-
/// <summary>
/// Allows one new RPC call to be received by server.
/// </summary>
@@ -233,7 +219,7 @@ namespace Grpc.Core
}
catch (Exception e)
{
- Console.WriteLine("Exception while handling RPC: " + e);
+ Logger.Warning(e, "Exception while handling RPC.");
}
}
diff --git a/src/csharp/Grpc.Core/ServerCallContext.cs b/src/csharp/Grpc.Core/ServerCallContext.cs
index 17a2eefd07..0c48adaea5 100644
--- a/src/csharp/Grpc.Core/ServerCallContext.cs
+++ b/src/csharp/Grpc.Core/ServerCallContext.cs
@@ -47,6 +47,7 @@ namespace Grpc.Core
private readonly string method;
private readonly string host;
+ private readonly string peer;
private readonly DateTime deadline;
private readonly Metadata requestHeaders;
private readonly CancellationToken cancellationToken;
@@ -54,10 +55,11 @@ namespace Grpc.Core
private Status status = Status.DefaultSuccess;
- public ServerCallContext(string method, string host, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken)
+ public ServerCallContext(string method, string host, string peer, DateTime deadline, Metadata requestHeaders, CancellationToken cancellationToken)
{
this.method = method;
this.host = host;
+ this.peer = peer;
this.deadline = deadline;
this.requestHeaders = requestHeaders;
this.cancellationToken = cancellationToken;
@@ -81,6 +83,15 @@ namespace Grpc.Core
}
}
+ /// <summary> Address of the remote endpoint in URI format. </summary>
+ public string Peer
+ {
+ get
+ {
+ return this.peer;
+ }
+ }
+
/// <summary> Deadline for this RPC. </summary>
public DateTime Deadline
{
diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs
index ab7d0b4914..32ed4b78a1 100644
--- a/src/csharp/Grpc.Core/ServerCredentials.cs
+++ b/src/csharp/Grpc.Core/ServerCredentials.cs
@@ -35,6 +35,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Grpc.Core.Internal;
+using Grpc.Core.Utils;
namespace Grpc.Core
{
@@ -43,67 +44,99 @@ namespace Grpc.Core
/// </summary>
public abstract class ServerCredentials
{
+ static readonly ServerCredentials InsecureInstance = new InsecureServerCredentialsImpl();
+
+ /// <summary>
+ /// Returns instance of credential that provides no security and
+ /// will result in creating an unsecure server port with no encryption whatsoever.
+ /// </summary>
+ public static ServerCredentials Insecure
+ {
+ get
+ {
+ return InsecureInstance;
+ }
+ }
+
/// <summary>
/// Creates native object for the credentials.
/// </summary>
/// <returns>The native credentials.</returns>
internal abstract ServerCredentialsSafeHandle ToNativeCredentials();
+
+ private sealed class InsecureServerCredentialsImpl : ServerCredentials
+ {
+ internal override ServerCredentialsSafeHandle ToNativeCredentials()
+ {
+ return null;
+ }
+ }
}
/// <summary>
- /// Key certificate pair (in PEM encoding).
+ /// Server-side SSL credentials.
/// </summary>
- public class KeyCertificatePair
+ public class SslServerCredentials : ServerCredentials
{
- readonly string certChain;
- readonly string privateKey;
+ readonly IList<KeyCertificatePair> keyCertificatePairs;
+ readonly string rootCertificates;
- public KeyCertificatePair(string certChain, string privateKey)
+ /// <summary>
+ /// Creates server-side SSL credentials.
+ /// </summary>
+ /// <param name="rootCertificates">PEM encoded client root certificates used to authenticate client.</param>
+ /// <param name="keyCertificatePairs">Key-certificates to use.</param>
+ public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates)
{
- this.certChain = certChain;
- this.privateKey = privateKey;
+ this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly();
+ Preconditions.CheckArgument(this.keyCertificatePairs.Count > 0,
+ "At least one KeyCertificatePair needs to be provided");
+ this.rootCertificates = rootCertificates;
}
- public string CertChain
+ /// <summary>
+ /// Creates server-side SSL credentials.
+ /// This constructor should be use if you do not wish to autheticate client
+ /// using client root certificates.
+ /// </summary>
+ /// <param name="keyCertificatePairs">Key-certificates to use.</param>
+ public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs) : this(keyCertificatePairs, null)
{
- get
- {
- return certChain;
- }
}
- public string PrivateKey
+ /// <summary>
+ /// Key-certificate pairs.
+ /// </summary>
+ public IList<KeyCertificatePair> KeyCertificatePairs
{
get
{
- return privateKey;
+ return this.keyCertificatePairs;
}
}
- }
-
- /// <summary>
- /// Server-side SSL credentials.
- /// </summary>
- public class SslServerCredentials : ServerCredentials
- {
- ImmutableList<KeyCertificatePair> keyCertPairs;
- public SslServerCredentials(ImmutableList<KeyCertificatePair> keyCertPairs)
+ /// <summary>
+ /// PEM encoded client root certificates.
+ /// </summary>
+ public string RootCertificates
{
- this.keyCertPairs = keyCertPairs;
+ get
+ {
+ return this.rootCertificates;
+ }
}
internal override ServerCredentialsSafeHandle ToNativeCredentials()
{
- int count = keyCertPairs.Count;
+ int count = keyCertificatePairs.Count;
string[] certChains = new string[count];
string[] keys = new string[count];
for (int i = 0; i < count; i++)
{
- certChains[i] = keyCertPairs[i].CertChain;
- keys[i] = keyCertPairs[i].PrivateKey;
+ certChains[i] = keyCertificatePairs[i].CertificateChain;
+ keys[i] = keyCertificatePairs[i].PrivateKey;
}
- return ServerCredentialsSafeHandle.CreateSslCredentials(certChains, keys);
+ return ServerCredentialsSafeHandle.CreateSslCredentials(rootCertificates, certChains, keys);
}
}
}
diff --git a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
index 4180d98938..82653c3a1f 100644
--- a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
+++ b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
@@ -46,13 +46,15 @@ namespace Grpc.Core.Utils
/// </summary>
public static void RunBenchmark(int warmupIterations, int benchmarkIterations, Action action)
{
- Console.WriteLine("Warmup iterations: " + warmupIterations);
+ var logger = GrpcEnvironment.Logger;
+
+ logger.Info("Warmup iterations: {0}", warmupIterations);
for (int i = 0; i < warmupIterations; i++)
{
action();
}
- Console.WriteLine("Benchmark iterations: " + benchmarkIterations);
+ logger.Info("Benchmark iterations: {0}", benchmarkIterations);
var stopwatch = new Stopwatch();
stopwatch.Start();
for (int i = 0; i < benchmarkIterations; i++)
@@ -60,8 +62,8 @@ namespace Grpc.Core.Utils
action();
}
stopwatch.Stop();
- Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms");
- Console.WriteLine("Ops per second: " + (int)((double)benchmarkIterations * 1000 / stopwatch.ElapsedMilliseconds));
+ logger.Info("Elapsed time: {0}ms", stopwatch.ElapsedMilliseconds);
+ logger.Info("Ops per second: {0}", (int)((double)benchmarkIterations * 1000 / stopwatch.ElapsedMilliseconds));
}
}
}
diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
index 5d5401593d..85996a570c 100644
--- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
+++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
@@ -2,7 +2,7 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}</ProjectGuid>
@@ -11,7 +11,7 @@
<AssemblyName>MathClient</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -20,16 +20,16 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
diff --git a/src/csharp/Grpc.Examples.MathClient/MathClient.cs b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
index cfe2a06916..f9839d99f1 100644
--- a/src/csharp/Grpc.Examples.MathClient/MathClient.cs
+++ b/src/csharp/Grpc.Examples.MathClient/MathClient.cs
@@ -39,7 +39,7 @@ namespace math
{
public static void Main(string[] args)
{
- using (Channel channel = new Channel("127.0.0.1", 23456))
+ using (Channel channel = new Channel("127.0.0.1", 23456, Credentials.Insecure))
{
Math.IMathClient client = new Math.MathClient(channel);
MathExamples.DivExample(client);
diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
index 677d87da20..6c8856cc92 100644
--- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
+++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
@@ -2,7 +2,7 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>10.0.0</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{BF62FE08-373A-43D6-9D73-41CAA38B7011}</ProjectGuid>
@@ -11,7 +11,7 @@
<AssemblyName>MathServer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -20,16 +20,16 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
index f440985112..468eefbe3e 100644
--- a/src/csharp/Grpc.Examples.MathServer/MathServer.cs
+++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs
@@ -44,7 +44,7 @@ namespace math
Server server = new Server();
server.AddServiceDefinition(Math.BindService(new MathServiceImpl()));
- int port = server.AddListeningPort(host, 23456);
+ int port = server.AddPort(host, 23456, ServerCredentials.Insecure);
server.Start();
Console.WriteLine("MathServer listening on port " + port);
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index 7a957c5b6f..26f332c1cf 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -56,9 +56,9 @@ namespace math.Tests
{
server = new Server();
server.AddServiceDefinition(Math.BindService(new MathServiceImpl()));
- int port = server.AddListeningPort(host, Server.PickUnusedPort);
+ int port = server.AddPort(host, Server.PickUnusedPort, ServerCredentials.Insecure);
server.Start();
- channel = new Channel(host, port);
+ channel = new Channel(host, port, Credentials.Insecure);
client = Math.NewClient(channel);
// TODO(jtattermusch): get rid of the custom header here once we have dedicated tests
@@ -108,69 +108,105 @@ namespace math.Tests
}
[Test]
- public void DivAsync()
+ public async Task DivAsync()
{
- Task.Run(async () =>
+ DivReply response = await client.DivAsync(new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build());
+ Assert.AreEqual(3, response.Quotient);
+ Assert.AreEqual(1, response.Remainder);
+ }
+
+ [Test]
+ public async Task Fib()
+ {
+ using (var call = client.Fib(new FibArgs.Builder { Limit = 6 }.Build()))
{
- DivReply response = await client.DivAsync(new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build());
- Assert.AreEqual(3, response.Quotient);
- Assert.AreEqual(1, response.Remainder);
- }).Wait();
+ var responses = await call.ResponseStream.ToList();
+ CollectionAssert.AreEqual(new List<long> { 1, 1, 2, 3, 5, 8 },
+ responses.ConvertAll((n) => n.Num_));
+ }
}
[Test]
- public void Fib()
+ public async Task FibWithCancel()
{
- Task.Run(async () =>
+ var cts = new CancellationTokenSource();
+
+ using (var call = client.Fib(new FibArgs.Builder { Limit = 0 }.Build(),
+ cancellationToken: cts.Token))
{
- using (var call = client.Fib(new FibArgs.Builder { Limit = 6 }.Build()))
+ List<long> responses = new List<long>();
+
+ try
+ {
+ while (await call.ResponseStream.MoveNext())
+ {
+ if (responses.Count == 0)
+ {
+ cts.CancelAfter(500); // make sure we cancel soon
+ }
+ responses.Add(call.ResponseStream.Current.Num_);
+ }
+ Assert.Fail();
+ }
+ catch (RpcException e)
{
- var responses = await call.ResponseStream.ToList();
- CollectionAssert.AreEqual(new List<long> { 1, 1, 2, 3, 5, 8 },
- responses.ConvertAll((n) => n.Num_));
+ Assert.IsTrue(responses.Count > 0);
+ Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
}
- }).Wait();
+ }
}
- // TODO: test Fib with limit=0 and cancellation
[Test]
- public void Sum()
+ public async Task FibWithDeadline()
{
- Task.Run(async () =>
+ using (var call = client.Fib(new FibArgs.Builder { Limit = 0 }.Build(),
+ deadline: DateTime.UtcNow.AddMilliseconds(500)))
{
- using (var call = client.Sum())
+ try
{
- var numbers = new List<long> { 10, 20, 30 }.ConvertAll(
- n => Num.CreateBuilder().SetNum_(n).Build());
-
- await call.RequestStream.WriteAll(numbers);
- var result = await call.ResponseAsync;
- Assert.AreEqual(60, result.Num_);
+ await call.ResponseStream.ToList();
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.DeadlineExceeded, e.Status.StatusCode);
}
- }).Wait();
+ }
}
+ // TODO: test Fib with limit=0 and cancellation
[Test]
- public void DivMany()
+ public async Task Sum()
{
- Task.Run(async () =>
+ using (var call = client.Sum())
{
- var divArgsList = new List<DivArgs>
- {
- new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build(),
- new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(),
- new DivArgs.Builder { Dividend = 7, Divisor = 2 }.Build()
- };
+ var numbers = new List<long> { 10, 20, 30 }.ConvertAll(
+ n => Num.CreateBuilder().SetNum_(n).Build());
- using (var call = client.DivMany())
- {
- await call.RequestStream.WriteAll(divArgsList);
- var result = await call.ResponseStream.ToList();
+ await call.RequestStream.WriteAll(numbers);
+ var result = await call.ResponseAsync;
+ Assert.AreEqual(60, result.Num_);
+ }
+ }
- CollectionAssert.AreEqual(new long[] { 3, 4, 3 }, result.ConvertAll((divReply) => divReply.Quotient));
- CollectionAssert.AreEqual(new long[] { 1, 16, 1 }, result.ConvertAll((divReply) => divReply.Remainder));
- }
- }).Wait();
+ [Test]
+ public async Task DivMany()
+ {
+ var divArgsList = new List<DivArgs>
+ {
+ new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build(),
+ new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(),
+ new DivArgs.Builder { Dividend = 7, Divisor = 2 }.Build()
+ };
+
+ using (var call = client.DivMany())
+ {
+ await call.RequestStream.WriteAll(divArgsList);
+ var result = await call.ResponseStream.ToList();
+
+ CollectionAssert.AreEqual(new long[] { 3, 4, 3 }, result.ConvertAll((divReply) => divReply.Quotient));
+ CollectionAssert.AreEqual(new long[] { 1, 16, 1 }, result.ConvertAll((divReply) => divReply.Remainder));
+ }
}
}
}
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index ef787cf1d8..67827e7b4f 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -44,11 +44,11 @@ namespace math {
// client interface
public interface IMathClient
{
- global::math.DivReply Div(global::math.DivArgs request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
+ global::math.DivReply Div(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
}
// server-side interface
@@ -66,29 +66,29 @@ namespace math {
public MathClient(Channel channel) : base(channel)
{
}
- public global::math.DivReply Div(global::math.DivArgs request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public global::math.DivReply Div(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_Div, headers);
+ var call = CreateCall(__ServiceName, __Method_Div, headers, deadline);
return Calls.BlockingUnaryCall(call, request, cancellationToken);
}
- public AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncUnaryCall<global::math.DivReply> DivAsync(global::math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_Div, headers);
+ var call = CreateCall(__ServiceName, __Method_Div, headers, deadline);
return Calls.AsyncUnaryCall(call, request, cancellationToken);
}
- public AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_DivMany, headers);
+ var call = CreateCall(__ServiceName, __Method_DivMany, headers, deadline);
return Calls.AsyncDuplexStreamingCall(call, cancellationToken);
}
- public AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_Fib, headers);
+ var call = CreateCall(__ServiceName, __Method_Fib, headers, deadline);
return Calls.AsyncServerStreamingCall(call, request, cancellationToken);
}
- public AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_Sum, headers);
+ var call = CreateCall(__ServiceName, __Method_Sum, headers, deadline);
return Calls.AsyncClientStreamingCall(call, cancellationToken);
}
}
diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs
index 3dd0f53a0d..dd26b1d350 100644
--- a/src/csharp/Grpc.Examples/MathServiceImpl.cs
+++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs
@@ -54,8 +54,13 @@ namespace math
{
if (request.Limit <= 0)
{
- // TODO(jtattermusch): support cancellation
- throw new NotImplementedException("Not implemented yet");
+ // keep streaming the sequence until cancelled.
+ IEnumerator<Num> fibEnumerator = FibInternal(long.MaxValue).GetEnumerator();
+ while (!context.CancellationToken.IsCancellationRequested && fibEnumerator.MoveNext())
+ {
+ await responseStream.WriteAsync(fibEnumerator.Current);
+ await Task.Delay(100);
+ }
}
if (request.Limit > 0)
diff --git a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
index bc14a0a62f..9d89698a8f 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs
@@ -59,9 +59,9 @@ namespace Grpc.HealthCheck.Tests
server = new Server();
server.AddServiceDefinition(Grpc.Health.V1Alpha.Health.BindService(serviceImpl));
- int port = server.AddListeningPort(Host, Server.PickUnusedPort);
+ int port = server.AddPort(Host, Server.PickUnusedPort, ServerCredentials.Insecure);
server.Start();
- channel = new Channel(Host, port);
+ channel = new Channel(Host, port, Credentials.Insecure);
client = Grpc.Health.V1Alpha.Health.NewClient(channel);
}
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 217127eca7..892cdb3f04 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -24,8 +24,8 @@ namespace Grpc.Health.V1Alpha {
// client interface
public interface IHealthClient
{
- global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
+ global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
}
// server-side interface
@@ -40,14 +40,14 @@ namespace Grpc.Health.V1Alpha {
public HealthClient(Channel channel) : base(channel)
{
}
- public global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public global::Grpc.Health.V1Alpha.HealthCheckResponse Check(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_Check, headers);
+ var call = CreateCall(__ServiceName, __Method_Check, headers, deadline);
return Calls.BlockingUnaryCall(call, request, cancellationToken);
}
- public AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncUnaryCall<global::Grpc.Health.V1Alpha.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1Alpha.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_Check, headers);
+ var call = CreateCall(__ServiceName, __Method_Check, headers, deadline);
return Calls.AsyncUnaryCall(call, request, cancellationToken);
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
index dc1d0a44c0..37d53d61e0 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -2,7 +2,7 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{3D166931-BA2D-416E-95A3-D36E8F6E90B9}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Grpc.IntegrationTesting.Client</RootNamespace>
@@ -10,7 +10,7 @@
<StartupObject>Grpc.IntegrationTesting.Client.Program</StartupObject>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -19,16 +19,16 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/app.config b/src/csharp/Grpc.IntegrationTesting.Client/app.config
index 966b777192..0a82bb4f16 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/app.config
+++ b/src/csharp/Grpc.IntegrationTesting.Client/app.config
@@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+ <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
index f03c8f3ce3..0f3b9eb510 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -2,7 +2,7 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A654F3B8-E859-4E6A-B30D-227527DBEF0D}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Grpc.IntegrationTesting.Server</RootNamespace>
@@ -10,7 +10,7 @@
<StartupObject>Grpc.IntegrationTesting.Server.Program</StartupObject>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -19,16 +19,16 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/app.config b/src/csharp/Grpc.IntegrationTesting.Server/app.config
index 966b777192..0a82bb4f16 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/app.config
+++ b/src/csharp/Grpc.IntegrationTesting.Server/app.config
@@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+ <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index d3c69ab9eb..db2e304d37 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -2,16 +2,15 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
- <ProductVersion>8.0.30703</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C61154BA-DD4A-4838-8420-0162A28925E0}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Grpc.IntegrationTesting</RootNamespace>
<AssemblyName>Grpc.IntegrationTesting</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <NuGetPackageImportStamp>041c163e</NuGetPackageImportStamp>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
@@ -20,45 +19,36 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
- <Reference Include="Google.Apis.Auth, Version=1.9.1.12395, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Auth.1.9.1\lib\net40\Google.Apis.Auth.dll</HintPath>
- </Reference>
- <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.1.12399, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Auth.1.9.1\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
- </Reference>
- <Reference Include="Google.Apis.Core, Version=1.9.1.12394, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Google.Apis.Core.1.9.1\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+ <Reference Include="BouncyCastle.Crypto">
+ <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
</Reference>
- <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Auth, Version=1.9.2.27817, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.dll</HintPath>
</Reference>
- <Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.2.27820, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
</Reference>
- <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Core, Version=1.9.2.27816, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
+ <HintPath>..\packages\Google.Apis.Core.1.9.2\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
</Reference>
- <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Newtonsoft.Json.6.0.6\lib\net45\Newtonsoft.Json.dll</HintPath>
+ <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
@@ -67,24 +57,32 @@
<Reference Include="Google.ProtocolBuffers">
<HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath>
</Reference>
- <Reference Include="System.Collections.Immutable, Version=1.1.36.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
- </Reference>
<Reference Include="System.Interactive.Async">
<HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
</Reference>
<Reference Include="System.Net" />
<Reference Include="System.Net.Http" />
- <Reference Include="System.Net.Http.Extensions, Version=2.2.28.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <Reference Include="System.Net.Http.Extensions, Version=2.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Extensions.dll</HintPath>
+ <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
</Reference>
- <Reference Include="System.Net.Http.Primitives, Version=4.2.28.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+ <Reference Include="System.Net.Http.Primitives, Version=4.2.29.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Microsoft.Net.Http.2.2.28\lib\net45\System.Net.Http.Primitives.dll</HintPath>
+ <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
+ <Reference Include="Microsoft.Threading.Tasks">
+ <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Threading.Tasks.Extensions">
+ <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
+ <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Collections.Immutable">
+ <HintPath>..\packages\System.Collections.Immutable.1.1.36\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll</HintPath>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs">
@@ -99,6 +97,7 @@
<Compile Include="InteropClient.cs" />
<Compile Include="TestCredentials.cs" />
<Compile Include="TestGrpc.cs" />
+ <Compile Include="SslCredentialsTest.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -133,9 +132,11 @@
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
- <Import Project="..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" />
- <Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
- <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
- <Error Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.14\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
+ <Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
</Target>
</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index ce255f9423..4f8a5a5da7 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -130,12 +130,12 @@ namespace Grpc.IntegrationTesting
client.HeaderInterceptor = OAuth2InterceptorFactory.Create(credential);
}
- RunTestCase(options.testCase, client);
+ RunTestCaseAsync(options.testCase, client).Wait();
}
GrpcEnvironment.Shutdown();
}
- private void RunTestCase(string testCase, TestService.TestServiceClient client)
+ private async Task RunTestCaseAsync(string testCase, TestService.TestServiceClient client)
{
switch (testCase)
{
@@ -146,16 +146,16 @@ namespace Grpc.IntegrationTesting
RunLargeUnary(client);
break;
case "client_streaming":
- RunClientStreaming(client);
+ await RunClientStreamingAsync(client);
break;
case "server_streaming":
- RunServerStreaming(client);
+ await RunServerStreamingAsync(client);
break;
case "ping_pong":
- RunPingPong(client);
+ await RunPingPongAsync(client);
break;
case "empty_stream":
- RunEmptyStream(client);
+ await RunEmptyStreamAsync(client);
break;
case "service_account_creds":
RunServiceAccountCreds(client);
@@ -170,10 +170,10 @@ namespace Grpc.IntegrationTesting
RunPerRpcCreds(client);
break;
case "cancel_after_begin":
- RunCancelAfterBegin(client);
+ await RunCancelAfterBeginAsync(client);
break;
case "cancel_after_first_response":
- RunCancelAfterFirstResponse(client);
+ await RunCancelAfterFirstResponseAsync(client);
break;
case "benchmark_empty_unary":
RunBenchmarkEmptyUnary(client);
@@ -207,118 +207,106 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static void RunClientStreaming(TestService.ITestServiceClient client)
+ public static async Task RunClientStreamingAsync(TestService.ITestServiceClient client)
{
- Task.Run(async () =>
- {
- Console.WriteLine("running client_streaming");
+ Console.WriteLine("running client_streaming");
- var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => StreamingInputCallRequest.CreateBuilder().SetPayload(CreateZerosPayload(size)).Build());
+ var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => StreamingInputCallRequest.CreateBuilder().SetPayload(CreateZerosPayload(size)).Build());
- using (var call = client.StreamingInputCall())
- {
- await call.RequestStream.WriteAll(bodySizes);
+ using (var call = client.StreamingInputCall())
+ {
+ await call.RequestStream.WriteAll(bodySizes);
- var response = await call.ResponseAsync;
- Assert.AreEqual(74922, response.AggregatedPayloadSize);
- }
- Console.WriteLine("Passed!");
- }).Wait();
+ var response = await call.ResponseAsync;
+ Assert.AreEqual(74922, response.AggregatedPayloadSize);
+ }
+ Console.WriteLine("Passed!");
}
- public static void RunServerStreaming(TestService.ITestServiceClient client)
+ public static async Task RunServerStreamingAsync(TestService.ITestServiceClient client)
{
- Task.Run(async () =>
- {
- Console.WriteLine("running server_streaming");
+ Console.WriteLine("running server_streaming");
- var bodySizes = new List<int> { 31415, 9, 2653, 58979 };
+ var bodySizes = new List<int> { 31415, 9, 2653, 58979 };
- var request = StreamingOutputCallRequest.CreateBuilder()
- .SetResponseType(PayloadType.COMPRESSABLE)
- .AddRangeResponseParameters(bodySizes.ConvertAll(
- (size) => ResponseParameters.CreateBuilder().SetSize(size).Build()))
- .Build();
+ var request = StreamingOutputCallRequest.CreateBuilder()
+ .SetResponseType(PayloadType.COMPRESSABLE)
+ .AddRangeResponseParameters(bodySizes.ConvertAll(
+ (size) => ResponseParameters.CreateBuilder().SetSize(size).Build()))
+ .Build();
- using (var call = client.StreamingOutputCall(request))
+ using (var call = client.StreamingOutputCall(request))
+ {
+ var responseList = await call.ResponseStream.ToList();
+ foreach (var res in responseList)
{
- var responseList = await call.ResponseStream.ToList();
- foreach (var res in responseList)
- {
- Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
- }
- CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
+ Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type);
}
- Console.WriteLine("Passed!");
- }).Wait();
+ CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
+ }
+ Console.WriteLine("Passed!");
}
- public static void RunPingPong(TestService.ITestServiceClient client)
+ public static async Task RunPingPongAsync(TestService.ITestServiceClient client)
{
- Task.Run(async () =>
- {
- Console.WriteLine("running ping_pong");
+ Console.WriteLine("running ping_pong");
- using (var call = client.FullDuplexCall())
- {
- await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
- .SetResponseType(PayloadType.COMPRESSABLE)
- .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
- .SetPayload(CreateZerosPayload(27182)).Build());
+ using (var call = client.FullDuplexCall())
+ {
+ await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
+ .SetResponseType(PayloadType.COMPRESSABLE)
+ .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
+ .SetPayload(CreateZerosPayload(27182)).Build());
- Assert.IsTrue(await call.ResponseStream.MoveNext());
- Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
- Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
+ Assert.IsTrue(await call.ResponseStream.MoveNext());
+ Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
+ Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
- await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
- .SetResponseType(PayloadType.COMPRESSABLE)
- .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9))
- .SetPayload(CreateZerosPayload(8)).Build());
+ await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
+ .SetResponseType(PayloadType.COMPRESSABLE)
+ .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9))
+ .SetPayload(CreateZerosPayload(8)).Build());
- Assert.IsTrue(await call.ResponseStream.MoveNext());
- Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
- Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
+ Assert.IsTrue(await call.ResponseStream.MoveNext());
+ Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
+ Assert.AreEqual(9, call.ResponseStream.Current.Payload.Body.Length);
- await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
- .SetResponseType(PayloadType.COMPRESSABLE)
- .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2653))
- .SetPayload(CreateZerosPayload(1828)).Build());
+ await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
+ .SetResponseType(PayloadType.COMPRESSABLE)
+ .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2653))
+ .SetPayload(CreateZerosPayload(1828)).Build());
- Assert.IsTrue(await call.ResponseStream.MoveNext());
- Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
- Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
+ Assert.IsTrue(await call.ResponseStream.MoveNext());
+ Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
+ Assert.AreEqual(2653, call.ResponseStream.Current.Payload.Body.Length);
- await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
- .SetResponseType(PayloadType.COMPRESSABLE)
- .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
- .SetPayload(CreateZerosPayload(45904)).Build());
+ await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
+ .SetResponseType(PayloadType.COMPRESSABLE)
+ .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979))
+ .SetPayload(CreateZerosPayload(45904)).Build());
- Assert.IsTrue(await call.ResponseStream.MoveNext());
- Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
- Assert.AreEqual(58979, call.ResponseStream.Current.Payload.Body.Length);
+ Assert.IsTrue(await call.ResponseStream.MoveNext());
+ Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
+ Assert.AreEqual(58979, call.ResponseStream.Current.Payload.Body.Length);
- await call.RequestStream.CompleteAsync();
+ await call.RequestStream.CompleteAsync();
- Assert.IsFalse(await call.ResponseStream.MoveNext());
- }
- Console.WriteLine("Passed!");
- }).Wait();
+ Assert.IsFalse(await call.ResponseStream.MoveNext());
+ }
+ Console.WriteLine("Passed!");
}
- public static void RunEmptyStream(TestService.ITestServiceClient client)
+ public static async Task RunEmptyStreamAsync(TestService.ITestServiceClient client)
{
- Task.Run(async () =>
+ Console.WriteLine("running empty_stream");
+ using (var call = client.FullDuplexCall())
{
- Console.WriteLine("running empty_stream");
- using (var call = client.FullDuplexCall())
- {
- await call.RequestStream.CompleteAsync();
+ await call.RequestStream.CompleteAsync();
- var responseList = await call.ResponseStream.ToList();
- Assert.AreEqual(0, responseList.Count);
- }
- Console.WriteLine("Passed!");
- }).Wait();
+ var responseList = await call.ResponseStream.ToList();
+ Assert.AreEqual(0, responseList.Count);
+ }
+ Console.WriteLine("Passed!");
}
public static void RunServiceAccountCreds(TestService.ITestServiceClient client)
@@ -406,65 +394,59 @@ namespace Grpc.IntegrationTesting
Console.WriteLine("Passed!");
}
- public static void RunCancelAfterBegin(TestService.ITestServiceClient client)
+ public static async Task RunCancelAfterBeginAsync(TestService.ITestServiceClient client)
{
- Task.Run(async () =>
+ Console.WriteLine("running cancel_after_begin");
+
+ var cts = new CancellationTokenSource();
+ using (var call = client.StreamingInputCall(cancellationToken: cts.Token))
{
- Console.WriteLine("running cancel_after_begin");
+ // TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
+ await Task.Delay(1000);
+ cts.Cancel();
- var cts = new CancellationTokenSource();
- using (var call = client.StreamingInputCall(cancellationToken: cts.Token))
+ try
{
- // TODO(jtattermusch): we need this to ensure call has been initiated once we cancel it.
- await Task.Delay(1000);
- cts.Cancel();
-
- try
- {
- var response = await call.ResponseAsync;
- Assert.Fail();
- }
- catch (RpcException e)
- {
- Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
- }
+ var response = await call.ResponseAsync;
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
}
- Console.WriteLine("Passed!");
- }).Wait();
+ }
+ Console.WriteLine("Passed!");
}
- public static void RunCancelAfterFirstResponse(TestService.ITestServiceClient client)
+ public static async Task RunCancelAfterFirstResponseAsync(TestService.ITestServiceClient client)
{
- Task.Run(async () =>
- {
- Console.WriteLine("running cancel_after_first_response");
+ Console.WriteLine("running cancel_after_first_response");
- var cts = new CancellationTokenSource();
- using (var call = client.FullDuplexCall(cancellationToken: cts.Token))
- {
- await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
- .SetResponseType(PayloadType.COMPRESSABLE)
- .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
- .SetPayload(CreateZerosPayload(27182)).Build());
+ var cts = new CancellationTokenSource();
+ using (var call = client.FullDuplexCall(cancellationToken: cts.Token))
+ {
+ await call.RequestStream.WriteAsync(StreamingOutputCallRequest.CreateBuilder()
+ .SetResponseType(PayloadType.COMPRESSABLE)
+ .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415))
+ .SetPayload(CreateZerosPayload(27182)).Build());
- Assert.IsTrue(await call.ResponseStream.MoveNext());
- Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
- Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
+ Assert.IsTrue(await call.ResponseStream.MoveNext());
+ Assert.AreEqual(PayloadType.COMPRESSABLE, call.ResponseStream.Current.Payload.Type);
+ Assert.AreEqual(31415, call.ResponseStream.Current.Payload.Body.Length);
- cts.Cancel();
+ cts.Cancel();
- try
- {
- await call.ResponseStream.MoveNext();
- Assert.Fail();
- }
- catch (RpcException e)
- {
- Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
- }
+ try
+ {
+ await call.ResponseStream.MoveNext();
+ Assert.Fail();
+ }
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
}
- Console.WriteLine("Passed!");
- }).Wait();
+ }
+ Console.WriteLine("Passed!");
}
// This is not an official interop test, but it's useful.
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
index f306289cfb..2756ce97aa 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -57,7 +57,7 @@ namespace Grpc.IntegrationTesting
{
server = new Server();
server.AddServiceDefinition(TestService.BindService(new TestServiceImpl()));
- int port = server.AddListeningPort(host, Server.PickUnusedPort, TestCredentials.CreateTestServerCredentials());
+ int port = server.AddPort(host, Server.PickUnusedPort, TestCredentials.CreateTestServerCredentials());
server.Start();
var options = new List<ChannelOption>
@@ -89,39 +89,39 @@ namespace Grpc.IntegrationTesting
}
[Test]
- public void ClientStreaming()
+ public async Task ClientStreaming()
{
- InteropClient.RunClientStreaming(client);
+ await InteropClient.RunClientStreamingAsync(client);
}
[Test]
- public void ServerStreaming()
+ public async Task ServerStreaming()
{
- InteropClient.RunServerStreaming(client);
+ await InteropClient.RunServerStreamingAsync(client);
}
[Test]
- public void PingPong()
+ public async Task PingPong()
{
- InteropClient.RunPingPong(client);
+ await InteropClient.RunPingPongAsync(client);
}
[Test]
- public void EmptyStream()
+ public async Task EmptyStream()
{
- InteropClient.RunEmptyStream(client);
+ await InteropClient.RunEmptyStreamAsync(client);
}
[Test]
- public void CancelAfterBegin()
+ public async Task CancelAfterBegin()
{
- InteropClient.RunCancelAfterBegin(client);
+ await InteropClient.RunCancelAfterBeginAsync(client);
}
[Test]
- public void CancelAfterFirstResponse()
+ public async Task CancelAfterFirstResponse()
{
- InteropClient.RunCancelAfterFirstResponse(client);
+ await InteropClient.RunCancelAfterFirstResponseAsync(client);
}
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
index 9475e66c40..bf6947e09d 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
@@ -95,11 +95,11 @@ namespace Grpc.IntegrationTesting
int port = options.port.Value;
if (options.useTls)
{
- server.AddListeningPort(host, port, TestCredentials.CreateTestServerCredentials());
+ server.AddPort(host, port, TestCredentials.CreateTestServerCredentials());
}
else
{
- server.AddListeningPort(host, options.port.Value);
+ server.AddPort(host, options.port.Value, ServerCredentials.Insecure);
}
Console.WriteLine("Running server on " + string.Format("{0}:{1}", host, port));
server.Start();
diff --git a/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
new file mode 100644
index 0000000000..1baf40eea2
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/SslCredentialsTest.cs
@@ -0,0 +1,97 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+using grpc.testing;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+ /// <summary>
+ /// Test SSL credentials where server authenticates client
+ /// and client authenticates the server.
+ /// </summary>
+ public class SslCredentialsTest
+ {
+ string host = "localhost";
+ Server server;
+ Channel channel;
+ TestService.ITestServiceClient client;
+
+ [TestFixtureSetUp]
+ public void Init()
+ {
+ var rootCert = File.ReadAllText(TestCredentials.ClientCertAuthorityPath);
+ var keyCertPair = new KeyCertificatePair(
+ File.ReadAllText(TestCredentials.ServerCertChainPath),
+ File.ReadAllText(TestCredentials.ServerPrivateKeyPath));
+
+ var serverCredentials = new SslServerCredentials(new[] { keyCertPair }, rootCert);
+ var clientCredentials = new SslCredentials(rootCert, keyCertPair);
+
+ server = new Server();
+ server.AddServiceDefinition(TestService.BindService(new TestServiceImpl()));
+ int port = server.AddPort(host, Server.PickUnusedPort, serverCredentials);
+ server.Start();
+
+ var options = new List<ChannelOption>
+ {
+ new ChannelOption(ChannelOptions.SslTargetNameOverride, TestCredentials.DefaultHostOverride)
+ };
+
+ channel = new Channel(host, port, clientCredentials, options);
+ client = TestService.NewClient(channel);
+ }
+
+ [TestFixtureTearDown]
+ public void Cleanup()
+ {
+ channel.Dispose();
+ server.ShutdownAsync().Wait();
+ GrpcEnvironment.Shutdown();
+ }
+
+ [Test]
+ public void AuthenticatedClientAndServer()
+ {
+ var response = client.UnaryCall(SimpleRequest.CreateBuilder().SetResponseSize(10).Build());
+ Assert.AreEqual(10, response.Payload.Body.Length);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
index 401c50b1ae..54d8587713 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
@@ -78,7 +78,7 @@ namespace Grpc.IntegrationTesting
var keyCertPair = new KeyCertificatePair(
File.ReadAllText(ServerCertChainPath),
File.ReadAllText(ServerPrivateKeyPath));
- return new SslServerCredentials(ImmutableList.Create(keyCertPair));
+ return new SslServerCredentials(new[] { keyCertPair });
}
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index de2fa07441..ddcd0c2958 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -59,14 +59,14 @@ namespace grpc.testing {
// client interface
public interface ITestServiceClient
{
- global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
- AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken));
+ global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+ AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
}
// server-side interface
@@ -86,44 +86,44 @@ namespace grpc.testing {
public TestServiceClient(Channel channel) : base(channel)
{
}
- public global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_EmptyCall, headers);
+ var call = CreateCall(__ServiceName, __Method_EmptyCall, headers, deadline);
return Calls.BlockingUnaryCall(call, request, cancellationToken);
}
- public AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncUnaryCall<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_EmptyCall, headers);
+ var call = CreateCall(__ServiceName, __Method_EmptyCall, headers, deadline);
return Calls.AsyncUnaryCall(call, request, cancellationToken);
}
- public global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_UnaryCall, headers);
+ var call = CreateCall(__ServiceName, __Method_UnaryCall, headers, deadline);
return Calls.BlockingUnaryCall(call, request, cancellationToken);
}
- public AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncUnaryCall<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_UnaryCall, headers);
+ var call = CreateCall(__ServiceName, __Method_UnaryCall, headers, deadline);
return Calls.AsyncUnaryCall(call, request, cancellationToken);
}
- public AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_StreamingOutputCall, headers);
+ var call = CreateCall(__ServiceName, __Method_StreamingOutputCall, headers, deadline);
return Calls.AsyncServerStreamingCall(call, request, cancellationToken);
}
- public AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_StreamingInputCall, headers);
+ var call = CreateCall(__ServiceName, __Method_StreamingInputCall, headers, deadline);
return Calls.AsyncClientStreamingCall(call, cancellationToken);
}
- public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_FullDuplexCall, headers);
+ var call = CreateCall(__ServiceName, __Method_FullDuplexCall, headers, deadline);
return Calls.AsyncDuplexStreamingCall(call, cancellationToken);
}
- public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, CancellationToken cancellationToken = default(CancellationToken))
+ public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
{
- var call = CreateCall(__ServiceName, __Method_HalfDuplexCall, headers);
+ var call = CreateCall(__ServiceName, __Method_HalfDuplexCall, headers, deadline);
return Calls.AsyncDuplexStreamingCall(call, cancellationToken);
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/app.config b/src/csharp/Grpc.IntegrationTesting/app.config
index 966b777192..0a82bb4f16 100644
--- a/src/csharp/Grpc.IntegrationTesting/app.config
+++ b/src/csharp/Grpc.IntegrationTesting/app.config
@@ -4,7 +4,7 @@
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
- <bindingRedirect oldVersion="0.0.0.0-4.2.28.0" newVersion="4.2.28.0" />
+ <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index c74ac75d79..746133a7a5 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="Google.Apis.Auth" version="1.9.1" targetFramework="net45" />
- <package id="Google.Apis.Core" version="1.9.1" targetFramework="net45" />
+ <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
+ <package id="Google.Apis.Auth" version="1.9.2" targetFramework="net45" />
+ <package id="Google.Apis.Core" version="1.9.2" targetFramework="net45" />
<package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
<package id="Ix-Async" version="1.2.3" targetFramework="net45" />
- <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
+ <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
<package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
- <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
- <package id="Microsoft.Net.Http" version="2.2.28" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="6.0.6" targetFramework="net45" />
+ <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
+ <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
<package id="NUnit" version="2.6.4" targetFramework="net45" />
<package id="System.Collections.Immutable" version="1.1.36" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index 705e4fb1c2..0cd8aaef6d 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -34,58 +34,58 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.HealthCheck.Tests", "G
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x86 = Debug|x86
- Release|x86 = Release|x86
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|x86.ActiveCfg = Debug|Any CPU
- {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|x86.Build.0 = Debug|Any CPU
- {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|x86.ActiveCfg = Release|Any CPU
- {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|x86.Build.0 = Release|Any CPU
- {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|x86.ActiveCfg = Debug|x86
- {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|x86.Build.0 = Debug|x86
- {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|x86.ActiveCfg = Release|x86
- {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|x86.Build.0 = Release|x86
- {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|x86.ActiveCfg = Debug|x86
- {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|x86.Build.0 = Debug|x86
- {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|x86.ActiveCfg = Release|x86
- {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|x86.Build.0 = Release|x86
- {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|x86.ActiveCfg = Debug|Any CPU
- {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|x86.Build.0 = Debug|Any CPU
- {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|x86.ActiveCfg = Release|Any CPU
- {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|x86.Build.0 = Release|Any CPU
- {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|x86.ActiveCfg = Debug|Any CPU
- {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|x86.Build.0 = Debug|Any CPU
- {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|x86.ActiveCfg = Release|Any CPU
- {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|x86.Build.0 = Release|Any CPU
- {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|x86.ActiveCfg = Debug|x86
- {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|x86.Build.0 = Debug|x86
- {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.ActiveCfg = Release|x86
- {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.Build.0 = Release|x86
- {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|x86.ActiveCfg = Debug|Any CPU
- {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|x86.Build.0 = Debug|Any CPU
- {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|x86.ActiveCfg = Release|Any CPU
- {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|x86.Build.0 = Release|Any CPU
- {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|x86.ActiveCfg = Debug|Any CPU
- {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|x86.Build.0 = Debug|Any CPU
- {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|x86.ActiveCfg = Release|Any CPU
- {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|x86.Build.0 = Release|Any CPU
- {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.ActiveCfg = Debug|x86
- {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|x86.Build.0 = Debug|x86
- {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.ActiveCfg = Release|x86
- {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|x86.Build.0 = Release|x86
- {C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.ActiveCfg = Debug|x86
- {C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.Build.0 = Debug|x86
- {C61154BA-DD4A-4838-8420-0162A28925E0}.Release|x86.ActiveCfg = Release|x86
- {C61154BA-DD4A-4838-8420-0162A28925E0}.Release|x86.Build.0 = Release|x86
- {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|x86.ActiveCfg = Debug|Any CPU
- {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|x86.Build.0 = Debug|Any CPU
- {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|x86.ActiveCfg = Release|Any CPU
- {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|x86.Build.0 = Release|Any CPU
- {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|x86.ActiveCfg = Debug|Any CPU
- {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|x86.Build.0 = Debug|Any CPU
- {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|x86.ActiveCfg = Release|Any CPU
- {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|x86.Build.0 = Release|Any CPU
+ {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index ae8186398a..6d15124d2c 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -366,7 +366,7 @@ grpcsharp_completion_queue_pluck(grpc_completion_queue *cq, void *tag) {
/* Channel */
GPR_EXPORT grpc_channel *GPR_CALLTYPE
-grpcsharp_channel_create(const char *target, const grpc_channel_args *args) {
+grpcsharp_insecure_channel_create(const char *target, const grpc_channel_args *args) {
return grpc_channel_create(target, args);
}
@@ -432,10 +432,20 @@ grpcsharp_channel_args_destroy(grpc_channel_args *args) {
/* Timespec */
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(void) { return gpr_now(GPR_CLOCK_REALTIME); }
+GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(gpr_clock_type clock_type) {
+ return gpr_now(clock_type);
+}
+
+GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(gpr_clock_type clock_type) {
+ return gpr_inf_future(clock_type);
+}
+
+GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_past(gpr_clock_type clock_type) {
+ return gpr_inf_past(clock_type);
+}
-GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(void) {
- return gpr_inf_future(GPR_CLOCK_REALTIME);
+GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_convert_clock_type(gpr_timespec t, gpr_clock_type target_clock) {
+ return gpr_convert_clock_type(t, target_clock);
}
GPR_EXPORT gpr_int32 GPR_CALLTYPE gprsharp_sizeof_timespec(void) {
@@ -454,6 +464,14 @@ grpcsharp_call_cancel_with_status(grpc_call *call, grpc_status_code status,
return grpc_call_cancel_with_status(call, status, description);
}
+GPR_EXPORT char *GPR_CALLTYPE grpcsharp_call_get_peer(grpc_call *call) {
+ return grpc_call_get_peer(call);
+}
+
+GPR_EXPORT void GPR_CALLTYPE gprsharp_free(void *p) {
+ gpr_free(p);
+}
+
GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
grpc_call_destroy(call);
}
@@ -695,7 +713,7 @@ grpcsharp_server_create(grpc_completion_queue *cq,
}
GPR_EXPORT gpr_int32 GPR_CALLTYPE
-grpcsharp_server_add_http2_port(grpc_server *server, const char *addr) {
+grpcsharp_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
return grpc_server_add_http2_port(server, addr);
}
diff --git a/src/node/README.md b/src/node/README.md
index 78781dab14..7d3d8c7fa1 100644
--- a/src/node/README.md
+++ b/src/node/README.md
@@ -85,7 +85,7 @@ An object with factory methods for creating credential objects for clients.
ServerCredentials
```
-An object with factory methods fro creating credential objects for servers.
+An object with factory methods for creating credential objects for servers.
[homebrew]:http://brew.sh
[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index 15c9b2d97d..dc45c8d8ae 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -192,7 +192,7 @@ class SendMetadataOp : public Op {
}
protected:
std::string GetTypeString() const {
- return "send metadata";
+ return "send_metadata";
}
};
@@ -216,7 +216,7 @@ class SendMessageOp : public Op {
}
protected:
std::string GetTypeString() const {
- return "send message";
+ return "send_message";
}
};
@@ -232,7 +232,7 @@ class SendClientCloseOp : public Op {
}
protected:
std::string GetTypeString() const {
- return "client close";
+ return "client_close";
}
};
@@ -276,7 +276,7 @@ class SendServerStatusOp : public Op {
}
protected:
std::string GetTypeString() const {
- return "send status";
+ return "send_status";
}
};
@@ -453,6 +453,8 @@ void Call::Init(Handle<Object> exports) {
NanNew<FunctionTemplate>(StartBatch)->GetFunction());
NanSetPrototypeTemplate(tpl, "cancel",
NanNew<FunctionTemplate>(Cancel)->GetFunction());
+ NanSetPrototypeTemplate(tpl, "getPeer",
+ NanNew<FunctionTemplate>(GetPeer)->GetFunction());
NanAssignPersistent(fun_tpl, tpl);
Handle<Function> ctr = tpl->GetFunction();
ctr->Set(NanNew("WRITE_BUFFER_HINT"),
@@ -608,5 +610,17 @@ NAN_METHOD(Call::Cancel) {
NanReturnUndefined();
}
+NAN_METHOD(Call::GetPeer) {
+ NanScope();
+ if (!HasInstance(args.This())) {
+ return NanThrowTypeError("getPeer can only be called on Call objects");
+ }
+ Call *call = ObjectWrap::Unwrap<Call>(args.This());
+ char *peer = grpc_call_get_peer(call->wrapped_call);
+ Handle<Value> peer_value = NanNew(peer);
+ gpr_free(peer);
+ NanReturnValue(peer_value);
+}
+
} // namespace node
} // namespace grpc
diff --git a/src/node/ext/call.h b/src/node/ext/call.h
index 43142c7091..6acda76197 100644
--- a/src/node/ext/call.h
+++ b/src/node/ext/call.h
@@ -120,6 +120,7 @@ class Call : public ::node::ObjectWrap {
static NAN_METHOD(New);
static NAN_METHOD(StartBatch);
static NAN_METHOD(Cancel);
+ static NAN_METHOD(GetPeer);
static NanCallback *constructor;
// Used for typechecking instances of this javascript class
static v8::Persistent<v8::FunctionTemplate> fun_tpl;
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index d37bf763dd..0b7333e450 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -76,6 +76,8 @@ void Channel::Init(Handle<Object> exports) {
tpl->InstanceTemplate()->SetInternalFieldCount(1);
NanSetPrototypeTemplate(tpl, "close",
NanNew<FunctionTemplate>(Close)->GetFunction());
+ NanSetPrototypeTemplate(tpl, "getTarget",
+ NanNew<FunctionTemplate>(GetTarget)->GetFunction());
NanAssignPersistent(fun_tpl, tpl);
Handle<Function> ctr = tpl->GetFunction();
constructor = new NanCallback(ctr);
@@ -185,5 +187,14 @@ NAN_METHOD(Channel::Close) {
NanReturnUndefined();
}
+NAN_METHOD(Channel::GetTarget) {
+ NanScope();
+ if (!HasInstance(args.This())) {
+ return NanThrowTypeError("getTarget can only be called on Channel objects");
+ }
+ Channel *channel = ObjectWrap::Unwrap<Channel>(args.This());
+ NanReturnValue(NanNew(grpc_channel_get_target(channel->wrapped_channel)));
+}
+
} // namespace node
} // namespace grpc
diff --git a/src/node/ext/channel.h b/src/node/ext/channel.h
index b3aa0f700f..6725ebb03f 100644
--- a/src/node/ext/channel.h
+++ b/src/node/ext/channel.h
@@ -66,6 +66,7 @@ class Channel : public ::node::ObjectWrap {
static NAN_METHOD(New);
static NAN_METHOD(Close);
+ static NAN_METHOD(GetTarget);
static NanCallback *constructor;
static v8::Persistent<v8::FunctionTemplate> fun_tpl;
diff --git a/src/node/ext/credentials.cc b/src/node/ext/credentials.cc
index 34872017ea..d6cff0631d 100644
--- a/src/node/ext/credentials.cc
+++ b/src/node/ext/credentials.cc
@@ -79,8 +79,6 @@ void Credentials::Init(Handle<Object> exports) {
NanNew<FunctionTemplate>(CreateComposite)->GetFunction());
ctr->Set(NanNew("createGce"),
NanNew<FunctionTemplate>(CreateGce)->GetFunction());
- ctr->Set(NanNew("createFake"),
- NanNew<FunctionTemplate>(CreateFake)->GetFunction());
ctr->Set(NanNew("createIam"),
NanNew<FunctionTemplate>(CreateIam)->GetFunction());
constructor = new NanCallback(ctr);
@@ -180,11 +178,6 @@ NAN_METHOD(Credentials::CreateGce) {
NanReturnValue(WrapStruct(grpc_compute_engine_credentials_create()));
}
-NAN_METHOD(Credentials::CreateFake) {
- NanScope();
- NanReturnValue(WrapStruct(grpc_fake_transport_security_credentials_create()));
-}
-
NAN_METHOD(Credentials::CreateIam) {
NanScope();
if (!args[0]->IsString()) {
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index 34cde9ffab..8554fce777 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -108,7 +108,7 @@ class NewCallOp : public Op {
protected:
std::string GetTypeString() const {
- return "new call";
+ return "new_call";
}
};
diff --git a/src/node/ext/server_credentials.cc b/src/node/ext/server_credentials.cc
index d2b63cdc4e..66aaa3300f 100644
--- a/src/node/ext/server_credentials.cc
+++ b/src/node/ext/server_credentials.cc
@@ -73,8 +73,6 @@ void ServerCredentials::Init(Handle<Object> exports) {
Handle<Function> ctr = tpl->GetFunction();
ctr->Set(NanNew("createSsl"),
NanNew<FunctionTemplate>(CreateSsl)->GetFunction());
- ctr->Set(NanNew("createFake"),
- NanNew<FunctionTemplate>(CreateFake)->GetFunction());
constructor = new NanCallback(ctr);
exports->Set(NanNew("ServerCredentials"), ctr);
}
@@ -144,11 +142,5 @@ NAN_METHOD(ServerCredentials::CreateSsl) {
grpc_ssl_server_credentials_create(root_certs, &key_cert_pair, 1)));
}
-NAN_METHOD(ServerCredentials::CreateFake) {
- NanScope();
- NanReturnValue(
- WrapStruct(grpc_fake_transport_security_server_credentials_create()));
-}
-
} // namespace node
} // namespace grpc
diff --git a/src/node/ext/server_credentials.h b/src/node/ext/server_credentials.h
index aaa7ef297a..80747504a1 100644
--- a/src/node/ext/server_credentials.h
+++ b/src/node/ext/server_credentials.h
@@ -63,7 +63,6 @@ class ServerCredentials : public ::node::ObjectWrap {
static NAN_METHOD(New);
static NAN_METHOD(CreateSsl);
- static NAN_METHOD(CreateFake);
static NanCallback *constructor;
// Used for typechecking instances of this javascript class
static v8::Persistent<v8::FunctionTemplate> fun_tpl;
diff --git a/src/node/ext/timeval.cc b/src/node/ext/timeval.cc
index 60de4d816d..bf68513c48 100644
--- a/src/node/ext/timeval.cc
+++ b/src/node/ext/timeval.cc
@@ -52,6 +52,7 @@ gpr_timespec MillisecondsToTimespec(double millis) {
}
double TimespecToMilliseconds(gpr_timespec timespec) {
+ timespec = gpr_convert_clock_type(timespec, GPR_CLOCK_REALTIME);
if (gpr_time_cmp(timespec, gpr_inf_future(GPR_CLOCK_REALTIME)) == 0) {
return std::numeric_limits<double>::infinity();
} else if (gpr_time_cmp(timespec, gpr_inf_past(GPR_CLOCK_REALTIME)) == 0) {
diff --git a/src/node/src/client.js b/src/node/src/client.js
index da6327b432..d89c656c07 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -188,6 +188,19 @@ ClientWritableStream.prototype.cancel = cancel;
ClientDuplexStream.prototype.cancel = cancel;
/**
+ * Get the endpoint this call/stream is connected to.
+ * @return {string} The URI of the endpoint
+ */
+function getPeer() {
+ /* jshint validthis: true */
+ return this.call.getPeer();
+}
+
+ClientReadableStream.prototype.getPeer = getPeer;
+ClientWritableStream.prototype.getPeer = getPeer;
+ClientDuplexStream.prototype.getPeer = getPeer;
+
+/**
* Get a function that can make unary requests to the specified method.
* @param {string} method The name of the method to request
* @param {function(*):Buffer} serialize The serialization function for inputs
@@ -223,6 +236,9 @@ function makeUnaryRequestFunction(method, serialize, deserialize) {
emitter.cancel = function cancel() {
call.cancel();
};
+ emitter.getPeer = function getPeer() {
+ return call.getPeer();
+ };
this.updateMetadata(this.auth_uri, metadata, function(error, metadata) {
if (error) {
call.cancel();
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 0a3a0031bd..e876313d96 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -374,6 +374,19 @@ ServerDuplexStream.prototype._write = _write;
ServerDuplexStream.prototype.sendMetadata = sendMetadata;
/**
+ * Get the endpoint this call/stream is connected to.
+ * @return {string} The URI of the endpoint
+ */
+function getPeer() {
+ /* jshint validthis: true */
+ return this.call.getPeer();
+}
+
+ServerReadableStream.prototype.getPeer = getPeer;
+ServerWritableStream.prototype.getPeer = getPeer;
+ServerDuplexStream.prototype.getPeer = getPeer;
+
+/**
* Fully handle a unary call
* @param {grpc.Call} call The call to handle
* @param {Object} handler Request handler object for the method that was called
@@ -389,6 +402,9 @@ function handleUnary(call, handler, metadata) {
call.startBatch(batch, function() {});
}
};
+ emitter.getPeer = function() {
+ return call.getPeer();
+ };
emitter.on('error', function(error) {
handleError(call, error);
});
@@ -544,7 +560,7 @@ function Server(options) {
if (err) {
return;
}
- var details = event['new call'];
+ var details = event.new_call;
var call = details.call;
var method = details.method;
var metadata = details.metadata;
diff --git a/src/node/test/call_test.js b/src/node/test/call_test.js
index 98158ffff3..942c31ac68 100644
--- a/src/node/test/call_test.js
+++ b/src/node/test/call_test.js
@@ -132,7 +132,7 @@ describe('call', function() {
'key2': ['value2']};
call.startBatch(batch, function(err, resp) {
assert.ifError(err);
- assert.deepEqual(resp, {'send metadata': true});
+ assert.deepEqual(resp, {'send_metadata': true});
done();
});
});
@@ -147,7 +147,7 @@ describe('call', function() {
};
call.startBatch(batch, function(err, resp) {
assert.ifError(err);
- assert.deepEqual(resp, {'send metadata': true});
+ assert.deepEqual(resp, {'send_metadata': true});
done();
});
});
@@ -184,4 +184,10 @@ describe('call', function() {
});
});
});
+ describe('getPeer', function() {
+ it('should return a string', function() {
+ var call = new grpc.Call(channel, 'method', getDeadline(1));
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ });
+ });
});
diff --git a/src/node/test/channel_test.js b/src/node/test/channel_test.js
index 33200c99ee..3e61d3bbc6 100644
--- a/src/node/test/channel_test.js
+++ b/src/node/test/channel_test.js
@@ -87,4 +87,10 @@ describe('channel', function() {
});
});
});
+ describe('getTarget', function() {
+ it('should return a string', function() {
+ var channel = new grpc.Channel('localhost', {});
+ assert.strictEqual(typeof channel.getTarget(), 'string');
+ });
+ });
});
diff --git a/src/node/test/end_to_end_test.js b/src/node/test/end_to_end_test.js
index 667852f382..5d3baf823d 100644
--- a/src/node/test/end_to_end_test.js
+++ b/src/node/test/end_to_end_test.js
@@ -85,37 +85,37 @@ describe('end-to-end', function() {
call.startBatch(client_batch, function(err, response) {
assert.ifError(err);
assert.deepEqual(response, {
- 'send metadata': true,
- 'client close': true,
- 'metadata': {},
- 'status': {
- 'code': grpc.status.OK,
- 'details': status_text,
- 'metadata': {}
+ send_metadata: true,
+ client_close: true,
+ metadata: {},
+ status: {
+ code: grpc.status.OK,
+ details: status_text,
+ metadata: {}
}
});
done();
});
server.requestCall(function(err, call_details) {
- var new_call = call_details['new call'];
+ var new_call = call_details.new_call;
assert.notEqual(new_call, null);
var server_call = new_call.call;
assert.notEqual(server_call, null);
var server_batch = {};
server_batch[grpc.opType.SEND_INITIAL_METADATA] = {};
server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
- 'metadata': {},
- 'code': grpc.status.OK,
- 'details': status_text
+ metadata: {},
+ code: grpc.status.OK,
+ details: status_text
};
server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
server_call.startBatch(server_batch, function(err, response) {
assert.ifError(err);
assert.deepEqual(response, {
- 'send metadata': true,
- 'send status': true,
- 'cancelled': false
+ send_metadata: true,
+ send_status: true,
+ cancelled: false
});
done();
});
@@ -131,7 +131,7 @@ describe('end-to-end', function() {
Infinity);
var client_batch = {};
client_batch[grpc.opType.SEND_INITIAL_METADATA] = {
- 'client_key': ['client_value']
+ client_key: ['client_value']
};
client_batch[grpc.opType.SEND_CLOSE_FROM_CLIENT] = true;
client_batch[grpc.opType.RECV_INITIAL_METADATA] = true;
@@ -139,18 +139,18 @@ describe('end-to-end', function() {
call.startBatch(client_batch, function(err, response) {
assert.ifError(err);
assert.deepEqual(response,{
- 'send metadata': true,
- 'client close': true,
+ send_metadata: true,
+ client_close: true,
metadata: {server_key: ['server_value']},
- status: {'code': grpc.status.OK,
- 'details': status_text,
- 'metadata': {}}
+ status: {code: grpc.status.OK,
+ details: status_text,
+ metadata: {}}
});
done();
});
server.requestCall(function(err, call_details) {
- var new_call = call_details['new call'];
+ var new_call = call_details.new_call;
assert.notEqual(new_call, null);
assert.strictEqual(new_call.metadata.client_key[0],
'client_value');
@@ -158,20 +158,20 @@ describe('end-to-end', function() {
assert.notEqual(server_call, null);
var server_batch = {};
server_batch[grpc.opType.SEND_INITIAL_METADATA] = {
- 'server_key': ['server_value']
+ server_key: ['server_value']
};
server_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
- 'metadata': {},
- 'code': grpc.status.OK,
- 'details': status_text
+ metadata: {},
+ code: grpc.status.OK,
+ details: status_text
};
server_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
server_call.startBatch(server_batch, function(err, response) {
assert.ifError(err);
assert.deepEqual(response, {
- 'send metadata': true,
- 'send status': true,
- 'cancelled': false
+ send_metadata: true,
+ send_status: true,
+ cancelled: false
});
done();
});
@@ -196,19 +196,19 @@ describe('end-to-end', function() {
client_batch[grpc.opType.RECV_STATUS_ON_CLIENT] = true;
call.startBatch(client_batch, function(err, response) {
assert.ifError(err);
- assert(response['send metadata']);
- assert(response['client close']);
+ assert(response.send_metadata);
+ assert(response.client_close);
assert.deepEqual(response.metadata, {});
- assert(response['send message']);
+ assert(response.send_message);
assert.strictEqual(response.read.toString(), reply_text);
- assert.deepEqual(response.status, {'code': grpc.status.OK,
- 'details': status_text,
- 'metadata': {}});
+ assert.deepEqual(response.status, {code: grpc.status.OK,
+ details: status_text,
+ metadata: {}});
done();
});
server.requestCall(function(err, call_details) {
- var new_call = call_details['new call'];
+ var new_call = call_details.new_call;
assert.notEqual(new_call, null);
var server_call = new_call.call;
assert.notEqual(server_call, null);
@@ -217,18 +217,18 @@ describe('end-to-end', function() {
server_batch[grpc.opType.RECV_MESSAGE] = true;
server_call.startBatch(server_batch, function(err, response) {
assert.ifError(err);
- assert(response['send metadata']);
+ assert(response.send_metadata);
assert.strictEqual(response.read.toString(), req_text);
var response_batch = {};
response_batch[grpc.opType.SEND_MESSAGE] = new Buffer(reply_text);
response_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
- 'metadata': {},
- 'code': grpc.status.OK,
- 'details': status_text
+ metadata: {},
+ code: grpc.status.OK,
+ details: status_text
};
response_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
server_call.startBatch(response_batch, function(err, response) {
- assert(response['send status']);
+ assert(response.send_status);
assert(!response.cancelled);
done();
});
@@ -251,9 +251,9 @@ describe('end-to-end', function() {
call.startBatch(client_batch, function(err, response) {
assert.ifError(err);
assert.deepEqual(response, {
- 'send metadata': true,
- 'send message': true,
- 'metadata': {}
+ send_metadata: true,
+ send_message: true,
+ metadata: {}
});
var req2_batch = {};
req2_batch[grpc.opType.SEND_MESSAGE] = new Buffer(requests[1]);
@@ -262,12 +262,12 @@ describe('end-to-end', function() {
call.startBatch(req2_batch, function(err, resp) {
assert.ifError(err);
assert.deepEqual(resp, {
- 'send message': true,
- 'client close': true,
- 'status': {
- 'code': grpc.status.OK,
- 'details': status_text,
- 'metadata': {}
+ send_message: true,
+ client_close: true,
+ status: {
+ code: grpc.status.OK,
+ details: status_text,
+ metadata: {}
}
});
done();
@@ -275,7 +275,7 @@ describe('end-to-end', function() {
});
server.requestCall(function(err, call_details) {
- var new_call = call_details['new call'];
+ var new_call = call_details.new_call;
assert.notEqual(new_call, null);
var server_call = new_call.call;
assert.notEqual(server_call, null);
@@ -284,7 +284,7 @@ describe('end-to-end', function() {
server_batch[grpc.opType.RECV_MESSAGE] = true;
server_call.startBatch(server_batch, function(err, response) {
assert.ifError(err);
- assert(response['send metadata']);
+ assert(response.send_metadata);
assert.strictEqual(response.read.toString(), requests[0]);
var snd_batch = {};
snd_batch[grpc.opType.RECV_MESSAGE] = true;
@@ -294,13 +294,13 @@ describe('end-to-end', function() {
var end_batch = {};
end_batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;
end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
- 'metadata': {},
- 'code': grpc.status.OK,
- 'details': status_text
+ metadata: {},
+ code: grpc.status.OK,
+ details: status_text
};
server_call.startBatch(end_batch, function(err, response) {
assert.ifError(err);
- assert(response['send status']);
+ assert(response.send_status);
assert(!response.cancelled);
done();
});
diff --git a/src/node/test/server_test.js b/src/node/test/server_test.js
index 7cb34fa0cb..9c7bb465aa 100644
--- a/src/node/test/server_test.js
+++ b/src/node/test/server_test.js
@@ -34,6 +34,8 @@
'use strict';
var assert = require('assert');
+var fs = require('fs');
+var path = require('path');
var grpc = require('bindings')('grpc.node');
describe('server', function() {
@@ -67,9 +69,13 @@ describe('server', function() {
before(function() {
server = new grpc.Server();
});
- it('should bind to an unused port with fake credentials', function() {
+ it('should bind to an unused port with ssl credentials', function() {
var port;
- var creds = grpc.ServerCredentials.createFake();
+ var key_path = path.join(__dirname, '../test/data/server1.key');
+ var pem_path = path.join(__dirname, '../test/data/server1.pem');
+ var key_data = fs.readFileSync(key_path);
+ var pem_data = fs.readFileSync(pem_path);
+ var creds = grpc.ServerCredentials.createSsl(null, key_data, pem_data);
assert.doesNotThrow(function() {
port = server.addSecureHttp2Port('0.0.0.0:0', creds);
});
diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js
index 1dbe4e2805..98f9b15bfc 100644
--- a/src/node/test/surface_test.js
+++ b/src/node/test/surface_test.js
@@ -343,6 +343,9 @@ describe('Other conditions', function() {
after(function() {
server.shutdown();
});
+ it('channel.getTarget should be available', function() {
+ assert.strictEqual(typeof client.channel.getTarget(), 'string');
+ });
describe('Server recieving bad input', function() {
var misbehavingClient;
var badArg = new Buffer([0xFF]);
@@ -548,6 +551,43 @@ describe('Other conditions', function() {
});
});
});
+ describe('call.getPeer should return the peer', function() {
+ it('for a unary call', function(done) {
+ var call = client.unary({error: false}, function(err, data) {
+ assert.ifError(err);
+ done();
+ });
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ });
+ it('for a client stream call', function(done) {
+ var call = client.clientStream(function(err, data) {
+ assert.ifError(err);
+ done();
+ });
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ call.write({error: false});
+ call.end();
+ });
+ it('for a server stream call', function(done) {
+ var call = client.serverStream({error: false});
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ assert.strictEqual(status.code, grpc.status.OK);
+ done();
+ });
+ });
+ it('for a bidi stream call', function(done) {
+ var call = client.bidiStream();
+ assert.strictEqual(typeof call.getPeer(), 'string');
+ call.write({error: false});
+ call.end();
+ call.on('data', function(){});
+ call.on('status', function(status) {
+ done();
+ });
+ });
+ });
});
describe('Cancelling surface client', function() {
var client;
diff --git a/src/php/composer.json b/src/php/composer.json
index b0115bdadd..2d0fe0c87a 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -1,7 +1,7 @@
{
"name": "grpc/grpc",
"description": "gRPC library for PHP",
- "version": "0.5.0",
+ "version": "0.5.1",
"homepage": "http://grpc.io",
"license": "BSD-3-Clause",
"repositories": [
diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c
index a262b9981f..01cb94e3aa 100644
--- a/src/php/ext/grpc/credentials.c
+++ b/src/php/ext/grpc/credentials.c
@@ -175,23 +175,12 @@ PHP_METHOD(Credentials, createGce) {
RETURN_DESTROY_ZVAL(creds_object);
}
-/**
- * Create fake credentials. Only to be used for testing.
- * @return Credentials The new fake credentials object
- */
-PHP_METHOD(Credentials, createFake) {
- grpc_credentials *creds = grpc_fake_transport_security_credentials_create();
- zval *creds_object = grpc_php_wrap_credentials(creds);
- RETURN_DESTROY_ZVAL(creds_object);
-}
-
static zend_function_entry credentials_methods[] = {
PHP_ME(Credentials, createDefault, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Credentials, createSsl, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Credentials, createComposite, NULL,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_ME(Credentials, createGce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
- PHP_ME(Credentials, createFake, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
PHP_FE_END};
void grpc_init_credentials(TSRMLS_D) {
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index c4c1fabb1a..4c4a598cb0 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -121,21 +121,8 @@ PHP_METHOD(ServerCredentials, createSsl) {
RETURN_DESTROY_ZVAL(creds_object);
}
-/**
- * Create fake credentials. Only to be used for testing.
- * @return ServerCredentials The new fake credentials object
- */
-PHP_METHOD(ServerCredentials, createFake) {
- grpc_server_credentials *creds =
- grpc_fake_transport_security_server_credentials_create();
- zval *creds_object = grpc_php_wrap_server_credentials(creds);
- RETURN_DESTROY_ZVAL(creds_object);
-}
-
static zend_function_entry server_credentials_methods[] = {
PHP_ME(ServerCredentials, createSsl, NULL,
- ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
- PHP_ME(ServerCredentials, createFake, NULL,
ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END};
void grpc_init_server_credentials(TSRMLS_D) {
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index 48c00977eb..8c438e4bf9 100755
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -60,7 +60,10 @@ class BaseStub {
}
unset($opts['update_metadata']);
}
-
+ $package_config = json_decode(
+ file_get_contents(dirname(__FILE__) . '/../../composer.json'), true);
+ $opts['grpc.primary_user_agent'] =
+ 'grpc-php/' . $package_config['version'];
$this->channel = new Channel($hostname, $opts);
}
diff --git a/src/python/src/grpc/_adapter/_c/types.h b/src/python/src/grpc/_adapter/_c/types.h
index 3449f0643f..4e0da4a28a 100644
--- a/src/python/src/grpc/_adapter/_c/types.h
+++ b/src/python/src/grpc/_adapter/_c/types.h
@@ -63,8 +63,6 @@ ClientCredentials *pygrpc_ClientCredentials_jwt(
PyTypeObject *type, PyObject *args, PyObject *kwargs);
ClientCredentials *pygrpc_ClientCredentials_refresh_token(
PyTypeObject *type, PyObject *args, PyObject *kwargs);
-ClientCredentials *pygrpc_ClientCredentials_fake_transport_security(
- PyTypeObject *type, PyObject *ignored);
ClientCredentials *pygrpc_ClientCredentials_iam(
PyTypeObject *type, PyObject *args, PyObject *kwargs);
extern PyTypeObject pygrpc_ClientCredentials_type;
@@ -81,8 +79,6 @@ typedef struct ServerCredentials {
void pygrpc_ServerCredentials_dealloc(ServerCredentials *self);
ServerCredentials *pygrpc_ServerCredentials_ssl(
PyTypeObject *type, PyObject *args, PyObject *kwargs);
-ServerCredentials *pygrpc_ServerCredentials_fake_transport_security(
- PyTypeObject *type, PyObject *ignored);
extern PyTypeObject pygrpc_ServerCredentials_type;
diff --git a/src/python/src/grpc/_adapter/_c/types/client_credentials.c b/src/python/src/grpc/_adapter/_c/types/client_credentials.c
index 6a4561c060..e314c15324 100644
--- a/src/python/src/grpc/_adapter/_c/types/client_credentials.c
+++ b/src/python/src/grpc/_adapter/_c/types/client_credentials.c
@@ -54,9 +54,6 @@ PyMethodDef pygrpc_ClientCredentials_methods[] = {
METH_CLASS|METH_KEYWORDS, ""},
{"refresh_token", (PyCFunction)pygrpc_ClientCredentials_refresh_token,
METH_CLASS|METH_KEYWORDS, ""},
- {"fake_transport_security",
- (PyCFunction)pygrpc_ClientCredentials_fake_transport_security,
- METH_CLASS|METH_NOARGS, ""},
{"iam", (PyCFunction)pygrpc_ClientCredentials_iam,
METH_CLASS|METH_KEYWORDS, ""},
{NULL}
@@ -208,6 +205,7 @@ ClientCredentials *pygrpc_ClientCredentials_service_account(
return self;
}
+/* TODO: Rename this credentials to something like service_account_jwt_access */
ClientCredentials *pygrpc_ClientCredentials_jwt(
PyTypeObject *type, PyObject *args, PyObject *kwargs) {
ClientCredentials *self;
@@ -219,7 +217,7 @@ ClientCredentials *pygrpc_ClientCredentials_jwt(
return NULL;
}
self = (ClientCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_jwt_credentials_create(
+ self->c_creds = grpc_service_account_jwt_access_credentials_create(
json_key, pygrpc_cast_double_to_gpr_timespec(lifetime));
if (!self->c_creds) {
Py_DECREF(self);
@@ -249,20 +247,6 @@ ClientCredentials *pygrpc_ClientCredentials_refresh_token(
return self;
}
-ClientCredentials *pygrpc_ClientCredentials_fake_transport_security(
- PyTypeObject *type, PyObject *ignored) {
- ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_fake_transport_security_credentials_create();
- if (!self->c_creds) {
- Py_DECREF(self);
- PyErr_SetString(PyExc_RuntimeError,
- "couldn't create fake credentials; "
- "something is horribly wrong with the universe");
- return NULL;
- }
- return self;
-}
-
ClientCredentials *pygrpc_ClientCredentials_iam(
PyTypeObject *type, PyObject *args, PyObject *kwargs) {
ClientCredentials *self;
diff --git a/src/python/src/grpc/_adapter/_c/types/server_credentials.c b/src/python/src/grpc/_adapter/_c/types/server_credentials.c
index 2e02c8fe81..f22edbf187 100644
--- a/src/python/src/grpc/_adapter/_c/types/server_credentials.c
+++ b/src/python/src/grpc/_adapter/_c/types/server_credentials.c
@@ -43,9 +43,6 @@
PyMethodDef pygrpc_ServerCredentials_methods[] = {
{"ssl", (PyCFunction)pygrpc_ServerCredentials_ssl,
METH_CLASS|METH_KEYWORDS, ""},
- {"fake_transport_security",
- (PyCFunction)pygrpc_ServerCredentials_fake_transport_security,
- METH_CLASS|METH_NOARGS, ""},
{NULL}
};
const char pygrpc_ServerCredentials_doc[] = "";
@@ -137,10 +134,3 @@ ServerCredentials *pygrpc_ServerCredentials_ssl(
return self;
}
-ServerCredentials *pygrpc_ServerCredentials_fake_transport_security(
- PyTypeObject *type, PyObject *ignored) {
- ServerCredentials *self = (ServerCredentials *)type->tp_alloc(type, 0);
- self->c_creds = grpc_fake_transport_security_server_credentials_create();
- return self;
-}
-
diff --git a/src/python/src/grpc/_adapter/_c/utility.c b/src/python/src/grpc/_adapter/_c/utility.c
index d9f911a41a..51f3c9be01 100644
--- a/src/python/src/grpc/_adapter/_c/utility.c
+++ b/src/python/src/grpc/_adapter/_c/utility.c
@@ -374,6 +374,7 @@ PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops) {
}
double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec) {
+ timespec = gpr_convert_clock_type(timespec, GPR_CLOCK_REALTIME);
return timespec.tv_sec + 1e-9*timespec.tv_nsec;
}
diff --git a/src/python/src/grpc/_adapter/_c_test.py b/src/python/src/grpc/_adapter/_c_test.py
index 133b124072..fe020e2a9c 100644
--- a/src/python/src/grpc/_adapter/_c_test.py
+++ b/src/python/src/grpc/_adapter/_c_test.py
@@ -36,14 +36,6 @@ from grpc._adapter import _types
class CTypeSmokeTest(unittest.TestCase):
- def testClientCredentialsUpDown(self):
- credentials = _c.ClientCredentials.fake_transport_security()
- del credentials
-
- def testServerCredentialsUpDown(self):
- credentials = _c.ServerCredentials.fake_transport_security()
- del credentials
-
def testCompletionQueueUpDown(self):
completion_queue = _c.CompletionQueue()
del completion_queue
@@ -58,10 +50,6 @@ class CTypeSmokeTest(unittest.TestCase):
channel = _c.Channel('[::]:0', [])
del channel
- def testSecureChannelUpDown(self):
- channel = _c.Channel('[::]:0', [], _c.ClientCredentials.fake_transport_security())
- del channel
-
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/python/src/grpc/_cython/_cygrpc/credentials.pyx b/src/python/src/grpc/_cython/_cygrpc/credentials.pyx
index c14d8844dd..2d74702fbd 100644
--- a/src/python/src/grpc/_cython/_cygrpc/credentials.pyx
+++ b/src/python/src/grpc/_cython/_cygrpc/credentials.pyx
@@ -126,6 +126,7 @@ def client_credentials_service_account(
credentials.references.extend([json_key, scope])
return credentials
+#TODO rename to something like client_credentials_service_account_jwt_access.
def client_credentials_jwt(json_key, records.Timespec token_lifetime not None):
if isinstance(json_key, bytes):
pass
@@ -134,7 +135,7 @@ def client_credentials_jwt(json_key, records.Timespec token_lifetime not None):
else:
raise TypeError("expected json_key to be str or bytes")
cdef ClientCredentials credentials = ClientCredentials()
- credentials.c_credentials = grpc.grpc_jwt_credentials_create(
+ credentials.c_credentials = grpc.grpc_service_account_jwt_access_credentials_create(
json_key, token_lifetime.c_time)
credentials.references.append(json_key)
return credentials
@@ -152,12 +153,6 @@ def client_credentials_refresh_token(json_refresh_token):
credentials.references.append(json_refresh_token)
return credentials
-def client_credentials_fake_transport_security():
- cdef ClientCredentials credentials = ClientCredentials()
- credentials.c_credentials = (
- grpc.grpc_fake_transport_security_credentials_create())
- return credentials
-
def client_credentials_iam(authorization_token, authority_selector):
if isinstance(authorization_token, bytes):
pass
@@ -210,8 +205,3 @@ def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs):
)
return credentials
-def server_credentials_fake_transport_security():
- cdef ServerCredentials credentials = ServerCredentials()
- credentials.c_credentials = (
- grpc.grpc_fake_transport_security_server_credentials_create())
- return credentials
diff --git a/src/python/src/grpc/_cython/_cygrpc/grpc.pxd b/src/python/src/grpc/_cython/_cygrpc/grpc.pxd
index 7db8fbe31c..d065383587 100644
--- a/src/python/src/grpc/_cython/_cygrpc/grpc.pxd
+++ b/src/python/src/grpc/_cython/_cygrpc/grpc.pxd
@@ -313,11 +313,10 @@ cdef extern from "grpc/grpc_security.h":
grpc_credentials *grpc_compute_engine_credentials_create()
grpc_credentials *grpc_service_account_credentials_create(
const char *json_key, const char *scope, gpr_timespec token_lifetime)
- grpc_credentials *grpc_jwt_credentials_create(const char *json_key,
+ grpc_credentials *grpc_service_account_jwt_access_credentials_create(const char *json_key,
gpr_timespec token_lifetime)
grpc_credentials *grpc_refresh_token_credentials_create(
const char *json_refresh_token)
- grpc_credentials *grpc_fake_transport_security_credentials_create()
grpc_credentials *grpc_iam_credentials_create(const char *authorization_token,
const char *authority_selector)
void grpc_credentials_release(grpc_credentials *creds)
@@ -334,7 +333,6 @@ cdef extern from "grpc/grpc_security.h":
const char *pem_root_certs,
grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
size_t num_key_cert_pairs);
- grpc_server_credentials *grpc_fake_transport_security_server_credentials_create()
void grpc_server_credentials_release(grpc_server_credentials *creds)
int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
diff --git a/src/python/src/grpc/_cython/adapter_low.py b/src/python/src/grpc/_cython/adapter_low.py
index 7546dd1599..2bb468eece 100644
--- a/src/python/src/grpc/_cython/adapter_low.py
+++ b/src/python/src/grpc/_cython/adapter_low.py
@@ -72,10 +72,6 @@ class ClientCredentials(object):
raise NotImplementedError()
@staticmethod
- def fake_transport_security():
- raise NotImplementedError()
-
- @staticmethod
def iam():
raise NotImplementedError()
@@ -88,10 +84,6 @@ class ServerCredentials(object):
def ssl():
raise NotImplementedError()
- @staticmethod
- def fake_transport_security():
- raise NotImplementedError()
-
class CompletionQueue(type_interfaces.CompletionQueue):
def __init__(self):
diff --git a/src/python/src/grpc/_cython/cygrpc.pyx b/src/python/src/grpc/_cython/cygrpc.pyx
index dcb06f345c..f4d9661580 100644
--- a/src/python/src/grpc/_cython/cygrpc.pyx
+++ b/src/python/src/grpc/_cython/cygrpc.pyx
@@ -82,12 +82,8 @@ client_credentials_compute_engine = (
credentials.client_credentials_compute_engine)
client_credentials_jwt = credentials.client_credentials_jwt
client_credentials_refresh_token = credentials.client_credentials_refresh_token
-client_credentials_fake_transport_security = (
- credentials.client_credentials_fake_transport_security)
client_credentials_iam = credentials.client_credentials_iam
server_credentials_ssl = credentials.server_credentials_ssl
-server_credentials_fake_transport_security = (
- credentials.server_credentials_fake_transport_security)
CompletionQueue = completion_queue.CompletionQueue
Channel = channel.Channel
diff --git a/src/python/src/grpc/_cython/cygrpc_test.py b/src/python/src/grpc/_cython/cygrpc_test.py
index 838e1e2254..22d210b16b 100644
--- a/src/python/src/grpc/_cython/cygrpc_test.py
+++ b/src/python/src/grpc/_cython/cygrpc_test.py
@@ -76,14 +76,6 @@ class TypeSmokeTest(unittest.TestCase):
timespec = cygrpc.Timespec(now)
self.assertAlmostEqual(now, float(timespec), places=8)
- def testClientCredentialsUpDown(self):
- credentials = cygrpc.client_credentials_fake_transport_security()
- del credentials
-
- def testServerCredentialsUpDown(self):
- credentials = cygrpc.server_credentials_fake_transport_security()
- del credentials
-
def testCompletionQueueUpDown(self):
completion_queue = cygrpc.CompletionQueue()
del completion_queue
@@ -96,12 +88,6 @@ class TypeSmokeTest(unittest.TestCase):
channel = cygrpc.Channel('[::]:0', cygrpc.ChannelArgs([]))
del channel
- def testSecureChannelUpDown(self):
- channel = cygrpc.Channel(
- '[::]:0', cygrpc.ChannelArgs([]),
- cygrpc.client_credentials_fake_transport_security())
- del channel
-
@unittest.skip('TODO(atash): undo skip after #2229 is merged')
def testServerStartNoExplicitShutdown(self):
server = cygrpc.Server()
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 829f825597..65d9c9a237 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -209,10 +209,12 @@ static ID id_to_s;
/* Converts a wrapped time constant to a standard time. */
static VALUE grpc_rb_time_val_to_time(VALUE self) {
gpr_timespec *time_const = NULL;
+ gpr_timespec real_time;
TypedData_Get_Struct(self, gpr_timespec, &grpc_rb_timespec_data_type,
time_const);
- return rb_funcall(rb_cTime, id_at, 2, INT2NUM(time_const->tv_sec),
- INT2NUM(time_const->tv_nsec));
+ real_time = gpr_convert_clock_type(*time_const, GPR_CLOCK_REALTIME);
+ return rb_funcall(rb_cTime, id_at, 2, INT2NUM(real_time.tv_sec),
+ INT2NUM(real_time.tv_nsec));
}
/* Invokes inspect on the ctime version of the time val. */
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index e3a0a5ad80..375a651d24 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -213,6 +213,7 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
grpc_call_error err;
request_call_stack st;
VALUE result;
+ gpr_timespec deadline;
TypedData_Get_Struct(self, grpc_rb_server, &grpc_rb_server_data_type, s);
if (s->wrapped == NULL) {
rb_raise(rb_eRuntimeError, "destroyed!");
@@ -245,15 +246,13 @@ static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
}
/* build the NewServerRpc struct result */
+ deadline = gpr_convert_clock_type(st.details.deadline, GPR_CLOCK_REALTIME);
result = rb_struct_new(
- grpc_rb_sNewServerRpc,
- rb_str_new2(st.details.method),
+ grpc_rb_sNewServerRpc, rb_str_new2(st.details.method),
rb_str_new2(st.details.host),
- rb_funcall(rb_cTime, id_at, 2, INT2NUM(st.details.deadline.tv_sec),
- INT2NUM(st.details.deadline.tv_nsec)),
- grpc_rb_md_ary_to_h(&st.md_ary),
- grpc_rb_wrap_call(call),
- NULL);
+ rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
+ INT2NUM(deadline.tv_nsec)),
+ grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call), NULL);
grpc_request_call_stack_cleanup(&st);
return result;
}
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index d3fea9680a..dd6e0d7bb3 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -826,8 +826,9 @@ static void on_jwt_creds_get_metadata_failure(void *user_data,
static void test_jwt_creds_success(void) {
char *json_key_string = test_json_key_str();
- grpc_credentials *jwt_creds = grpc_jwt_credentials_create(
- json_key_string, grpc_max_auth_token_lifetime);
+ grpc_credentials *jwt_creds =
+ grpc_service_account_jwt_access_credentials_create(
+ json_key_string, grpc_max_auth_token_lifetime);
GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
@@ -858,8 +859,9 @@ static void test_jwt_creds_success(void) {
static void test_jwt_creds_signing_failure(void) {
char *json_key_string = test_json_key_str();
- grpc_credentials *jwt_creds = grpc_jwt_credentials_create(
- json_key_string, grpc_max_auth_token_lifetime);
+ grpc_credentials *jwt_creds =
+ grpc_service_account_jwt_access_credentials_create(
+ json_key_string, grpc_max_auth_token_lifetime);
GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
@@ -900,7 +902,7 @@ static grpc_credentials *composite_inner_creds(grpc_credentials *creds,
}
static void test_google_default_creds_auth_key(void) {
- grpc_jwt_credentials *jwt;
+ grpc_service_account_jwt_access_credentials *jwt;
grpc_credentials *creds;
char *json_key = test_json_key_str();
grpc_flush_cached_google_default_credentials();
@@ -909,7 +911,7 @@ static void test_google_default_creds_auth_key(void) {
gpr_free(json_key);
creds = grpc_google_default_credentials_create();
GPR_ASSERT(creds != NULL);
- jwt = (grpc_jwt_credentials *)composite_inner_creds(
+ jwt = (grpc_service_account_jwt_access_credentials *)composite_inner_creds(
creds, GRPC_CREDENTIALS_TYPE_JWT);
GPR_ASSERT(
strcmp(jwt->key.client_id,
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 616142b14e..5b351c169e 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -35,17 +35,17 @@
#include <thread>
#include "src/core/security/credentials.h"
+#include "test/core/end2end/data/ssl_test_data.h"
#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 "test/cpp/util/fake_credentials.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++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -83,13 +83,12 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
}
}
-template <typename T>
-void CheckAuthContext(T* context) {
+void CheckServerAuthContext(const ServerContext* context) {
std::shared_ptr<const AuthContext> auth_ctx = context->auth_context();
- std::vector<grpc::string> fake =
+ std::vector<grpc::string> ssl =
auth_ctx->FindPropertyValues("transport_security_type");
- EXPECT_EQ(1u, fake.size());
- EXPECT_EQ("fake", fake[0]);
+ EXPECT_EQ(1u, ssl.size());
+ EXPECT_EQ("ssl", ssl[0]);
EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty());
EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty());
}
@@ -142,7 +141,12 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
}
}
if (request->has_param() && request->param().check_auth_context()) {
- CheckAuthContext(context);
+ CheckServerAuthContext(context);
+ }
+ if (request->has_param() &&
+ request->param().response_message_length() > 0) {
+ response->set_message(
+ grpc::string(request->param().response_message_length(), '\0'));
}
return Status::OK;
}
@@ -235,10 +239,15 @@ class End2endTest : public ::testing::Test {
server_address_ << "localhost:" << port;
// Setup server
ServerBuilder builder;
+ SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
+ test_server1_cert};
+ SslServerCredentialsOptions ssl_opts;
+ ssl_opts.pem_root_certs = "";
+ ssl_opts.pem_key_cert_pairs.push_back(pkcp);
builder.AddListeningPort(server_address_.str(),
- FakeTransportSecurityServerCredentials());
+ SslServerCredentials(ssl_opts));
builder.RegisterService(&service_);
- builder.RegisterService("special", &special_service_);
+ builder.RegisterService("foo.test.youtube.com", &special_service_);
builder.SetMaxMessageSize(
kMaxMessageSize_); // For testing max message size.
builder.RegisterService(&dup_pkg_service_);
@@ -249,13 +258,16 @@ class End2endTest : public ::testing::Test {
void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
void ResetStub() {
+ SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
ChannelArguments args;
+ args.SetSslTargetNameOverride("foo.test.google.fr");
args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
- std::shared_ptr<ChannelInterface> channel = CreateChannel(
- server_address_.str(), FakeTransportSecurityCredentials(), args);
- stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
+ channel_ = CreateChannel(server_address_.str(), SslCredentials(ssl_opts),
+ args);
+ stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel_));
}
+ std::shared_ptr<ChannelInterface> channel_;
std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
@@ -263,7 +275,7 @@ class End2endTest : public ::testing::Test {
TestServiceImpl service_;
TestServiceImpl special_service_;
TestServiceImplDupPkg dup_pkg_service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
@@ -289,11 +301,11 @@ TEST_F(End2endTest, SimpleRpcWithHost) {
request.set_message("Hello");
ClientContext context;
- context.set_authority("special");
+ context.set_authority("foo.test.youtube.com");
Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(response.has_param());
- EXPECT_EQ(response.param().host(), "special");
+ EXPECT_EQ("special", response.param().host());
EXPECT_TRUE(s.ok());
}
@@ -482,24 +494,19 @@ TEST_F(End2endTest, BidiStream) {
// Talk to the two services with the same name but different package names.
// The two stubs are created on the same channel.
TEST_F(End2endTest, DiffPackageServices) {
- std::shared_ptr<ChannelInterface> channel =
- CreateChannel(server_address_.str(), FakeTransportSecurityCredentials(),
- ChannelArguments());
-
+ ResetStub();
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
- std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
- grpc::cpp::test::util::TestService::NewStub(channel));
ClientContext context;
- Status s = stub->Echo(&context, request, &response);
+ Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(s.ok());
std::unique_ptr<grpc::cpp::test::util::duplicate::TestService::Stub>
dup_pkg_stub(
- grpc::cpp::test::util::duplicate::TestService::NewStub(channel));
+ grpc::cpp::test::util::duplicate::TestService::NewStub(channel_));
ClientContext context2;
s = dup_pkg_stub->Echo(&context2, request, &response);
EXPECT_EQ("no package", response.message());
@@ -783,7 +790,32 @@ TEST_F(End2endTest, ClientAuthContext) {
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(s.ok());
- CheckAuthContext(&context);
+ std::shared_ptr<const AuthContext> auth_ctx = context.auth_context();
+ std::vector<grpc::string> ssl =
+ auth_ctx->FindPropertyValues("transport_security_type");
+ EXPECT_EQ(1u, ssl.size());
+ EXPECT_EQ("ssl", ssl[0]);
+ EXPECT_EQ("x509_subject_alternative_name",
+ auth_ctx->GetPeerIdentityPropertyName());
+ EXPECT_EQ(3u, auth_ctx->GetPeerIdentity().size());
+ EXPECT_EQ("*.test.google.fr", auth_ctx->GetPeerIdentity()[0]);
+ EXPECT_EQ("waterzooi.test.google.be", auth_ctx->GetPeerIdentity()[1]);
+ EXPECT_EQ("*.test.youtube.com", auth_ctx->GetPeerIdentity()[2]);
+}
+
+// Make the response larger than the flow control window.
+TEST_F(End2endTest, HugeResponse) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("huge response");
+ const size_t kResponseSize = 1024 * (1024 + 10);
+ request.mutable_param()->set_response_message_length(kResponseSize);
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(kResponseSize, response.message().size());
+ EXPECT_TRUE(s.ok());
}
} // namespace testing
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index 74b40d54d8..32130e24e9 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -42,7 +42,7 @@
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -260,7 +260,7 @@ class MockTest : public ::testing::Test {
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
TestServiceImpl service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
// Do one real rpc and one mocked one
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
index e47139641b..ff9c945c7c 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -43,7 +43,7 @@
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -208,7 +208,7 @@ class End2endTest : public ::testing::Test {
const int kMaxMessageSize_;
TestServiceImpl service_;
TestServiceImplDupPkg dup_pkg_service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index 48b1b2e864..73d82f7b88 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -123,7 +123,8 @@ std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey();
std::chrono::seconds token_lifetime = std::chrono::hours(1);
- creds = JWTCredentials(json_key, token_lifetime.count());
+ creds =
+ ServiceAccountJWTAccessCredentials(json_key, token_lifetime.count());
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "oauth2_auth_token") {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 846f8f31b0..33b6fa55c3 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -45,7 +45,6 @@
#include <grpc/support/host_port.h>
#include <grpc++/async_unary_call.h>
#include <grpc++/config.h>
-#include <grpc++/fixed_size_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index d90ff2212b..4c3c9cb497 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -40,6 +40,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc++/config.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/fixed_size_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
@@ -92,7 +93,13 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service {
class SynchronousServer GRPC_FINAL : public grpc::testing::Server {
public:
SynchronousServer(const ServerConfig& config, int port)
- : thread_pool_(config.threads()), impl_(MakeImpl(port)) {}
+ : thread_pool_(), impl_(MakeImpl(port)) {
+ if (config.threads() > 0) {
+ thread_pool_.reset(new FixedSizeThreadPool(config.threads()));
+ } else {
+ thread_pool_.reset(new DynamicThreadPool(-config.threads()));
+ }
+ }
private:
std::unique_ptr<grpc::Server> MakeImpl(int port) {
@@ -105,13 +112,13 @@ class SynchronousServer GRPC_FINAL : public grpc::testing::Server {
builder.RegisterService(&service_);
- builder.SetThreadPool(&thread_pool_);
+ builder.SetThreadPool(thread_pool_.get());
return builder.BuildAndStart();
}
TestServiceImpl service_;
- FixedSizeThreadPool thread_pool_;
+ std::unique_ptr<ThreadPoolInterface> thread_pool_;
std::unique_ptr<grpc::Server> impl_;
};
diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc
index 07289f699b..c1ba23decd 100644
--- a/test/cpp/qps/timer.cc
+++ b/test/cpp/qps/timer.cc
@@ -52,7 +52,7 @@ static double time_double(struct timeval* tv) {
Timer::Result Timer::Sample() {
struct rusage usage;
struct timeval tv;
- gettimeofday(&tv, nullptr);
+ gettimeofday(&tv, NULL);
getrusage(RUSAGE_SELF, &usage);
Result r;
diff --git a/test/cpp/util/fake_credentials.cc b/test/cpp/server/dynamic_thread_pool_test.cc
index f5b83b8159..63b603b8f7 100644
--- a/test/cpp/util/fake_credentials.cc
+++ b/test/cpp/server/dynamic_thread_pool_test.cc
@@ -31,28 +31,47 @@
*
*/
-#include <grpc/grpc_security.h>
-#include <grpc++/channel_arguments.h>
-#include <grpc++/credentials.h>
-#include <grpc++/server_credentials.h>
-#include "src/cpp/client/channel.h"
-#include "src/cpp/client/secure_credentials.h"
-#include "src/cpp/server/secure_server_credentials.h"
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+
+#include <grpc++/dynamic_thread_pool.h>
+#include <gtest/gtest.h>
namespace grpc {
-namespace testing {
-std::shared_ptr<Credentials> FakeTransportSecurityCredentials() {
- grpc_credentials* c_creds = grpc_fake_transport_security_credentials_create();
- return std::shared_ptr<Credentials>(new SecureCredentials(c_creds));
+class DynamicThreadPoolTest : public ::testing::Test {
+ public:
+ DynamicThreadPoolTest() : thread_pool_(0) {}
+
+ protected:
+ DynamicThreadPool thread_pool_;
+};
+
+void Callback(std::mutex* mu, std::condition_variable* cv, bool* done) {
+ std::unique_lock<std::mutex> lock(*mu);
+ *done = true;
+ cv->notify_all();
}
-std::shared_ptr<ServerCredentials> FakeTransportSecurityServerCredentials() {
- grpc_server_credentials* c_creds =
- grpc_fake_transport_security_server_credentials_create();
- return std::shared_ptr<ServerCredentials>(
- new SecureServerCredentials(c_creds));
+TEST_F(DynamicThreadPoolTest, Add) {
+ std::mutex mu;
+ std::condition_variable cv;
+ bool done = false;
+ std::function<void()> callback = std::bind(Callback, &mu, &cv, &done);
+ thread_pool_.Add(callback);
+
+ // Wait for the callback to finish.
+ std::unique_lock<std::mutex> lock(mu);
+ while (!done) {
+ cv.wait(lock);
+ }
}
-} // namespace testing
} // namespace grpc
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int result = RUN_ALL_TESTS();
+ return result;
+}
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
index 00bb821ae6..848a3aee57 100644
--- a/test/cpp/util/cli_call_test.cc
+++ b/test/cpp/util/cli_call_test.cc
@@ -39,7 +39,7 @@
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -102,7 +102,7 @@ class CliCallTest : public ::testing::Test {
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
TestServiceImpl service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
// Send a rpc with a normal stub and then a CliCall. Verify they match.
diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto
index 3708972b90..2fad8b42a2 100644
--- a/test/cpp/util/messages.proto
+++ b/test/cpp/util/messages.proto
@@ -38,6 +38,7 @@ message RequestParams {
optional int32 server_cancel_after_us = 3;
optional bool echo_metadata = 4;
optional bool check_auth_context = 5;
+ optional int32 response_message_length = 6;
}
message EchoRequest {
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 4bdd8babde..785779beb5 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -773,6 +773,7 @@ include/grpc++/config.h \
include/grpc++/config_protobuf.h \
include/grpc++/create_channel.h \
include/grpc++/credentials.h \
+include/grpc++/dynamic_thread_pool.h \
include/grpc++/fixed_size_thread_pool.h \
include/grpc++/generic_stub.h \
include/grpc++/impl/call.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 1c73ca6294..5cf6168388 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -773,6 +773,7 @@ include/grpc++/config.h \
include/grpc++/config_protobuf.h \
include/grpc++/create_channel.h \
include/grpc++/credentials.h \
+include/grpc++/dynamic_thread_pool.h \
include/grpc++/fixed_size_thread_pool.h \
include/grpc++/generic_stub.h \
include/grpc++/impl/call.h \
@@ -825,6 +826,7 @@ src/cpp/common/rpc_method.cc \
src/cpp/proto/proto_utils.cc \
src/cpp/server/async_generic_service.cc \
src/cpp/server/create_default_thread_pool.cc \
+src/cpp/server/dynamic_thread_pool.cc \
src/cpp/server/fixed_size_thread_pool.cc \
src/cpp/server/insecure_server_credentials.cc \
src/cpp/server/server.cc \
diff --git a/tools/run_tests/run_csharp.sh b/tools/run_tests/run_csharp.sh
index 752e83ef70..c0fedca193 100755
--- a/tools/run_tests/run_csharp.sh
+++ b/tools/run_tests/run_csharp.sh
@@ -32,6 +32,8 @@ set -ex
CONFIG=${CONFIG:-opt}
+NUNIT_CONSOLE="mono packages/NUnit.Runners.2.6.4/tools/nunit-console.exe"
+
if [ "$CONFIG" = "dbg" ]
then
MSBUILD_CONFIG="Debug"
@@ -46,6 +48,7 @@ root=`pwd`
cd src/csharp
export LD_LIBRARY_PATH=$root/libs/$CONFIG
-nunit-console -labels "$1/bin/$MSBUILD_CONFIG/$1.dll"
+
+$NUNIT_CONSOLE -labels "$1/bin/$MSBUILD_CONFIG/$1.dll"
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index c13df0dbf8..3bd70506d3 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1187,6 +1187,21 @@
"gpr_test_util",
"grpc",
"grpc++",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "language": "c++",
+ "name": "dynamic_thread_pool_test",
+ "src": [
+ "test/cpp/server/dynamic_thread_pool_test.cc"
+ ]
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc++",
"grpc++_test_util",
"grpc_test_util"
],
@@ -11570,6 +11585,7 @@
"include/grpc++/config_protobuf.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/dynamic_thread_pool.h",
"include/grpc++/fixed_size_thread_pool.h",
"include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
@@ -11619,6 +11635,7 @@
"include/grpc++/config_protobuf.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/dynamic_thread_pool.h",
"include/grpc++/fixed_size_thread_pool.h",
"include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
@@ -11669,6 +11686,7 @@
"src/cpp/proto/proto_utils.cc",
"src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc",
+ "src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/fixed_size_thread_pool.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/secure_server_credentials.cc",
@@ -11707,7 +11725,6 @@
"test/cpp/util/echo.pb.h",
"test/cpp/util/echo_duplicate.grpc.pb.h",
"test/cpp/util/echo_duplicate.pb.h",
- "test/cpp/util/fake_credentials.h",
"test/cpp/util/messages.grpc.pb.h",
"test/cpp/util/messages.pb.h",
"test/cpp/util/subprocess.h"
@@ -11719,8 +11736,6 @@
"test/cpp/util/cli_call.h",
"test/cpp/util/create_test_channel.cc",
"test/cpp/util/create_test_channel.h",
- "test/cpp/util/fake_credentials.cc",
- "test/cpp/util/fake_credentials.h",
"test/cpp/util/subprocess.cc",
"test/cpp/util/subprocess.h"
]
@@ -11744,6 +11759,7 @@
"include/grpc++/config_protobuf.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/dynamic_thread_pool.h",
"include/grpc++/fixed_size_thread_pool.h",
"include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
@@ -11790,6 +11806,7 @@
"include/grpc++/config_protobuf.h",
"include/grpc++/create_channel.h",
"include/grpc++/credentials.h",
+ "include/grpc++/dynamic_thread_pool.h",
"include/grpc++/fixed_size_thread_pool.h",
"include/grpc++/generic_stub.h",
"include/grpc++/impl/call.h",
@@ -11834,6 +11851,7 @@
"src/cpp/proto/proto_utils.cc",
"src/cpp/server/async_generic_service.cc",
"src/cpp/server/create_default_thread_pool.cc",
+ "src/cpp/server/dynamic_thread_pool.cc",
"src/cpp/server/fixed_size_thread_pool.cc",
"src/cpp/server/insecure_server_credentials.cc",
"src/cpp/server/server.cc",
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 2338a9599b..a7db65d9f8 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -678,6 +678,15 @@
{
"flaky": false,
"language": "c++",
+ "name": "dynamic_thread_pool_test",
+ "platforms": [
+ "windows",
+ "posix"
+ ]
+ },
+ {
+ "flaky": false,
+ "language": "c++",
"name": "end2end_test",
"platforms": [
"windows",
diff --git a/vsprojects/grpc++/grpc++.vcxproj b/vsprojects/grpc++/grpc++.vcxproj
index 2d13bf046b..51b91c6434 100644
--- a/vsprojects/grpc++/grpc++.vcxproj
+++ b/vsprojects/grpc++/grpc++.vcxproj
@@ -159,6 +159,7 @@
<ClInclude Include="..\..\include\grpc++\config_protobuf.h" />
<ClInclude Include="..\..\include\grpc++\create_channel.h" />
<ClInclude Include="..\..\include\grpc++\credentials.h" />
+ <ClInclude Include="..\..\include\grpc++\dynamic_thread_pool.h" />
<ClInclude Include="..\..\include\grpc++\fixed_size_thread_pool.h" />
<ClInclude Include="..\..\include\grpc++\generic_stub.h" />
<ClInclude Include="..\..\include\grpc++\impl\call.h" />
@@ -235,6 +236,8 @@
</ClCompile>
<ClCompile Include="..\..\src\cpp\server\create_default_thread_pool.cc">
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\dynamic_thread_pool.cc">
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\server\fixed_size_thread_pool.cc">
</ClCompile>
<ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc">
diff --git a/vsprojects/grpc++/grpc++.vcxproj.filters b/vsprojects/grpc++/grpc++.vcxproj.filters
index c5d8db57ae..85b743a8fb 100644
--- a/vsprojects/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/grpc++/grpc++.vcxproj.filters
@@ -61,6 +61,9 @@
<ClCompile Include="..\..\src\cpp\server\create_default_thread_pool.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\dynamic_thread_pool.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\server\fixed_size_thread_pool.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
@@ -132,6 +135,9 @@
<ClInclude Include="..\..\include\grpc++\credentials.h">
<Filter>include\grpc++</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\dynamic_thread_pool.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\fixed_size_thread_pool.h">
<Filter>include\grpc++</Filter>
</ClInclude>
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
index f03715b353..6886bbc2a0 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -159,6 +159,7 @@
<ClInclude Include="..\..\include\grpc++\config_protobuf.h" />
<ClInclude Include="..\..\include\grpc++\create_channel.h" />
<ClInclude Include="..\..\include\grpc++\credentials.h" />
+ <ClInclude Include="..\..\include\grpc++\dynamic_thread_pool.h" />
<ClInclude Include="..\..\include\grpc++\fixed_size_thread_pool.h" />
<ClInclude Include="..\..\include\grpc++\generic_stub.h" />
<ClInclude Include="..\..\include\grpc++\impl\call.h" />
@@ -222,6 +223,8 @@
</ClCompile>
<ClCompile Include="..\..\src\cpp\server\create_default_thread_pool.cc">
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\dynamic_thread_pool.cc">
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\server\fixed_size_thread_pool.cc">
</ClCompile>
<ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc">
diff --git a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 8f7f3bcd5e..7f109a2557 100644
--- a/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -46,6 +46,9 @@
<ClCompile Include="..\..\src\cpp\server\create_default_thread_pool.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
+ <ClCompile Include="..\..\src\cpp\server\dynamic_thread_pool.cc">
+ <Filter>src\cpp\server</Filter>
+ </ClCompile>
<ClCompile Include="..\..\src\cpp\server\fixed_size_thread_pool.cc">
<Filter>src\cpp\server</Filter>
</ClCompile>
@@ -117,6 +120,9 @@
<ClInclude Include="..\..\include\grpc++\credentials.h">
<Filter>include\grpc++</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\dynamic_thread_pool.h">
+ <Filter>include\grpc++</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\fixed_size_thread_pool.h">
<Filter>include\grpc++</Filter>
</ClInclude>