aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD4
-rw-r--r--Makefile51
-rw-r--r--build.json55
-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++/server_credentials.h3
-rw-r--r--include/grpc/grpc.h4
-rw-r--r--include/grpc/grpc_security.h21
-rw-r--r--src/compiler/csharp_generator.cc12
-rw-r--r--src/compiler/python_generator.cc2
-rw-r--r--src/core/channel/client_channel.c2
-rw-r--r--src/core/channel/compress_filter.c12
-rw-r--r--src/core/channel/http_client_filter.c4
-rw-r--r--src/core/channel/http_server_filter.c6
-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/client_auth_filter.c10
-rw-r--r--src/core/security/credentials.c31
-rw-r--r--src/core/security/credentials.h13
-rw-r--r--src/core/security/google_default_credentials.c5
-rw-r--r--src/core/security/security_connector.c7
-rw-r--r--src/core/security/security_connector.h1
-rw-r--r--src/core/support/stack_lockfree.c35
-rw-r--r--src/core/surface/call.c9
-rw-r--r--src/core/surface/channel.c22
-rw-r--r--src/core/surface/channel_create.c4
-rw-r--r--src/core/surface/server.c23
-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_encoder.c4
-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.c19
-rw-r--r--src/core/transport/metadata.c41
-rw-r--r--src/core/transport/metadata.h5
-rw-r--r--src/core/transport/transport_op_string.c10
-rw-r--r--src/core/tsi/ssl_transport_security.c8
-rw-r--r--src/core/tsi/ssl_transport_security.h16
-rw-r--r--src/cpp/client/insecure_credentials.cc2
-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/server/secure_server_credentials.cc3
-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.csproj53
-rw-r--r--src/csharp/Grpc.Auth/Grpc.Auth.nuspec9
-rw-r--r--src/csharp/Grpc.Auth/OAuth2Interceptors.cs (renamed from src/csharp/Grpc.Auth/OAuth2InterceptorFactory.cs)29
-rw-r--r--src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs2
-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.cs92
-rw-r--r--src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj37
-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.csproj23
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.nuspec6
-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/Properties/AssemblyInfo.cs8
-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.csproj21
-rw-r--r--src/csharp/Grpc.Examples.MathClient/MathClient.cs2
-rw-r--r--src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj21
-rw-r--r--src/csharp/Grpc.Examples.MathServer/MathServer.cs2
-rw-r--r--src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj13
-rw-r--r--src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs122
-rw-r--r--src/csharp/Grpc.Examples/Grpc.Examples.csproj13
-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/Grpc.HealthCheck.Tests.csproj11
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/HealthClientServerTest.cs4
-rw-r--r--src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj11
-rw-r--r--src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec6
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs12
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj23
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Client/app.config2
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj23
-rw-r--r--src/csharp/Grpc.IntegrationTesting.Server/app.config2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj90
-rw-r--r--src/csharp/Grpc.IntegrationTesting/InteropClient.cs267
-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.sln127
-rw-r--r--src/csharp/build_packages.bat2
-rw-r--r--src/csharp/buildall.bat5
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c34
-rw-r--r--src/csharp/keys/Grpc.public.snkbin0 -> 160 bytes
-rw-r--r--src/csharp/keys/README.md5
-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.cc15
-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.cc12
-rw-r--r--src/node/ext/server_credentials.h1
-rw-r--r--src/node/ext/timeval.cc1
-rw-r--r--src/node/index.js32
-rw-r--r--src/node/jsdoc_conf.json22
-rw-r--r--src/node/package.json4
-rw-r--r--src/node/src/client.js41
-rw-r--r--src/node/src/common.js52
-rw-r--r--src/node/src/server.js63
-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/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m2
-rw-r--r--src/php/composer.json2
-rw-r--r--src/php/ext/grpc/call.c14
-rw-r--r--src/php/ext/grpc/channel.c18
-rw-r--r--src/php/ext/grpc/credentials.c11
-rw-r--r--src/php/ext/grpc/server_credentials.c19
-rw-r--r--src/php/lib/Grpc/AbstractCall.php7
-rwxr-xr-xsrc/php/lib/Grpc/BaseStub.php12
-rw-r--r--src/php/tests/generated_code/AbstractGeneratedCodeTest.php7
-rwxr-xr-xsrc/php/tests/interop/interop_client.php9
-rwxr-xr-xsrc/php/tests/unit_tests/CallTest.php4
-rwxr-xr-xsrc/php/tests/unit_tests/EndToEndTest.php8
-rw-r--r--src/python/src/grpc/_adapter/_c/types.h4
-rw-r--r--src/python/src/grpc/_adapter/_c/types/channel.c2
-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.c14
-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/_adapter/_low_test.py2
-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/python/src/grpc/_links/_proto_scenarios.py4
-rw-r--r--src/python/src/grpc/framework/common/test_constants.py6
-rw-r--r--src/ruby/ext/grpc/rb_call.c4
-rw-r--r--src/ruby/ext/grpc/rb_channel.c2
-rw-r--r--src/ruby/ext/grpc/rb_grpc.c8
-rw-r--r--src/ruby/ext/grpc/rb_server.c13
-rw-r--r--src/ruby/ext/grpc/rb_server_credentials.c5
-rw-r--r--templates/vsprojects/Grpc.mak.template73
-rw-r--r--templates/vsprojects/build_test_protos.sh42
-rwxr-xr-xtemplates/vsprojects/generate_debug_projects.sh48
-rw-r--r--templates/vsprojects/sln_defs.include9
-rw-r--r--templates/vsprojects/vcxproj_defs.include27
-rw-r--r--test/core/end2end/dualstack_socket_test.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_compression.c3
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_fullstack_with_poll.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c2
-rw-r--r--test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c2
-rw-r--r--test/core/end2end/no_server_test.c2
-rw-r--r--test/core/end2end/tests/request_response_with_metadata_and_payload.c4
-rw-r--r--test/core/fling/client.c2
-rw-r--r--test/core/fling/server.c2
-rw-r--r--test/core/security/credentials_test.c14
-rw-r--r--test/core/transport/metadata_test.c16
-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/buildgen/generate_projects-old.sh76
-rwxr-xr-xtools/buildgen/plugins/generate_vsprojects.py2
-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/README.md65
-rw-r--r--vsprojects/cpptest.props18
-rw-r--r--vsprojects/global.props6
-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
-rw-r--r--vsprojects/make.bat5
224 files changed, 3725 insertions, 1478 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..850b404408 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": [
@@ -1895,6 +1895,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -1912,6 +1915,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -1970,6 +1976,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2048,6 +2057,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++",
@@ -2193,6 +2217,9 @@
"gpr_test_util",
"gpr",
"grpc++_test_config"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2211,6 +2238,9 @@
"gpr_test_util",
"gpr",
"grpc++_test_config"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2225,6 +2255,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2329,6 +2362,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2347,6 +2383,9 @@
"gpr_test_util",
"gpr",
"grpc++_test_config"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2365,6 +2404,9 @@
"gpr_test_util",
"gpr",
"grpc++_test_config"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2416,6 +2458,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2465,6 +2510,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
@@ -2482,6 +2530,9 @@
"grpc",
"gpr_test_util",
"gpr"
+ ],
+ "platforms": [
+ "posix"
]
},
{
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++/server_credentials.h b/include/grpc++/server_credentials.h
index 83ae9fd1eb..11acd67e8a 100644
--- a/include/grpc++/server_credentials.h
+++ b/include/grpc++/server_credentials.h
@@ -58,12 +58,15 @@ class ServerCredentials {
// Options to create ServerCredentials with SSL
struct SslServerCredentialsOptions {
+ SslServerCredentialsOptions() : force_client_auth(false) {}
+
struct PemKeyCertPair {
grpc::string private_key;
grpc::string cert_chain;
};
grpc::string pem_root_certs;
std::vector<PemKeyCertPair> pem_key_cert_pairs;
+ bool force_client_auth;
};
// Builds SSL ServerCredentials given SSL specific options
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 4080debb68..cf59b943e9 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -469,8 +469,8 @@ char *grpc_channel_get_target(grpc_channel *channel);
clients will want to simply pass NULL. See grpc_channel_args definition for
more on this. The data in 'args' need only live through the invocation of
this function. */
-grpc_channel *grpc_channel_create(const char *target,
- const grpc_channel_args *args);
+grpc_channel *grpc_insecure_channel_create(const char *target,
+ const grpc_channel_args *args);
/** Create a lame client: this client fails every operation attempted on it. */
grpc_channel *grpc_lame_client_channel_create(const char *target);
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 37d66c04ae..ff84050c6d 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -87,7 +87,7 @@ typedef struct {
directory).
- pem_key_cert_pair is a pointer on the object containing client's private
key and certificate chain. This parameter can be NULL if the client does
- not have such a key/cert pair. */
+ not have such a key/cert pair. */
grpc_credentials *grpc_ssl_credentials_create(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair);
@@ -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
@@ -177,14 +174,13 @@ void grpc_server_credentials_release(grpc_server_credentials *creds);
- pem_key_cert_pairs is an array private key / certificate chains of the
server. This parameter cannot be NULL.
- num_key_cert_pairs indicates the number of items in the private_key_files
- and cert_chain_files parameters. It should be at least 1. */
+ and cert_chain_files parameters. It should be at least 1.
+ - force_client_auth, if set to non-zero will force the client to authenticate
+ with an SSL cert. Note that this option is ignored if pem_root_certs is
+ NULL. */
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);
+ size_t num_key_cert_pairs, int force_client_auth);
/* --- Server-side secure ports. --- */
@@ -206,7 +202,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/compiler/python_generator.cc b/src/compiler/python_generator.cc
index 724b69c703..2982a89fad 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -249,7 +249,7 @@ bool GetModuleAndMessagePath(const Descriptor* type,
do {
message_path.push_back(path_elem_type);
path_elem_type = path_elem_type->containing_type();
- } while (path_elem_type != nullptr);
+ } while (path_elem_type); // implicit nullptr comparison; don't be explicit
grpc::string file_name = type->file()->name();
static const int proto_suffix_length = strlen(".proto");
if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
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..9fc8589fbb 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) {
@@ -282,19 +284,19 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
grpc_channel_args_get_compression_algorithm(args);
channeld->mdstr_request_compression_algorithm_key =
- grpc_mdstr_from_string(mdctx, GRPC_COMPRESS_REQUEST_ALGORITHM_KEY);
+ grpc_mdstr_from_string(mdctx, GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, 0);
channeld->mdstr_outgoing_compression_algorithm_key =
- grpc_mdstr_from_string(mdctx, "grpc-encoding");
+ grpc_mdstr_from_string(mdctx, "grpc-encoding", 0);
for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
- char *algorith_name;
- GPR_ASSERT(grpc_compression_algorithm_name(algo_idx, &algorith_name) != 0);
+ char *algorithm_name;
+ GPR_ASSERT(grpc_compression_algorithm_name(algo_idx, &algorithm_name) != 0);
channeld->mdelem_compression_algorithms[algo_idx] =
grpc_mdelem_from_metadata_strings(
mdctx,
grpc_mdstr_ref(channeld->mdstr_outgoing_compression_algorithm_key),
- grpc_mdstr_from_string(mdctx, algorith_name));
+ grpc_mdstr_from_string(mdctx, algorithm_name, 0));
}
GPR_ASSERT(!is_last);
diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c
index 6ae8488070..91125cb149 100644
--- a/src/core/channel/http_client_filter.c
+++ b/src/core/channel/http_client_filter.c
@@ -233,7 +233,7 @@ static grpc_mdstr *user_agent_from_args(grpc_mdctx *mdctx,
tmp = gpr_strvec_flatten(&v, NULL);
gpr_strvec_destroy(&v);
- result = grpc_mdstr_from_string(mdctx, tmp);
+ result = grpc_mdstr_from_string(mdctx, tmp, 0);
gpr_free(tmp);
return result;
@@ -260,7 +260,7 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
channeld->status = grpc_mdelem_from_strings(mdctx, ":status", "200");
channeld->user_agent = grpc_mdelem_from_metadata_strings(
- mdctx, grpc_mdstr_from_string(mdctx, "user-agent"),
+ mdctx, grpc_mdstr_from_string(mdctx, "user-agent", 0),
user_agent_from_args(mdctx, args));
}
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index 7c798d2fb4..9d89eb9bf2 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -250,9 +250,9 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http");
channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https");
channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc");
- channeld->path_key = grpc_mdstr_from_string(mdctx, ":path");
- channeld->authority_key = grpc_mdstr_from_string(mdctx, ":authority");
- channeld->host_key = grpc_mdstr_from_string(mdctx, "host");
+ channeld->path_key = grpc_mdstr_from_string(mdctx, ":path", 0);
+ channeld->authority_key = grpc_mdstr_from_string(mdctx, ":authority", 0);
+ channeld->host_key = grpc_mdstr_from_string(mdctx, "host", 0);
channeld->content_type =
grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
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/client_auth_filter.c b/src/core/security/client_auth_filter.c
index 9a69f53a5a..e86b5430b2 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -80,7 +80,7 @@ static void bubble_up_error(grpc_call_element *elem, const char *error_msg) {
channel_data *chand = elem->channel_data;
grpc_transport_stream_op_add_cancellation(
&calld->op, GRPC_STATUS_UNAUTHENTICATED,
- grpc_mdstr_from_string(chand->md_ctx, error_msg));
+ grpc_mdstr_from_string(chand->md_ctx, error_msg, 0));
grpc_call_next_op(elem, &calld->op);
}
@@ -316,10 +316,10 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
(grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(
sc, "client_auth_filter");
chand->md_ctx = metadata_context;
- chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority");
- chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path");
- chand->error_msg_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-message");
- chand->status_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-status");
+ chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority", 0);
+ chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path", 0);
+ chand->error_msg_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-message", 0);
+ chand->status_key = grpc_mdstr_from_string(chand->md_ctx, "grpc-status", 0);
}
/* Destructor for channel data */
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index fb59fa4b0e..15268cefbe 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -259,8 +259,10 @@ static void ssl_build_config(const char *pem_root_certs,
static void ssl_build_server_config(
const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
- size_t num_key_cert_pairs, grpc_ssl_server_config *config) {
+ size_t num_key_cert_pairs, int force_client_auth,
+ grpc_ssl_server_config *config) {
size_t i;
+ config->force_client_auth = force_client_auth;
if (pem_root_certs != NULL) {
ssl_copy_key_material(pem_root_certs, &config->pem_root_certs,
&config->pem_root_certs_size);
@@ -302,20 +304,20 @@ grpc_credentials *grpc_ssl_credentials_create(
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) {
+ size_t num_key_cert_pairs, int force_client_auth) {
grpc_ssl_server_credentials *c =
gpr_malloc(sizeof(grpc_ssl_server_credentials));
memset(c, 0, sizeof(grpc_ssl_server_credentials));
c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
c->base.vtable = &ssl_server_vtable;
ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
- num_key_cert_pairs, &c->config);
+ num_key_cert_pairs, force_client_auth, &c->config);
return &c->base;
}
/* -- 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 +330,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 +349,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 +403,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 +423,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/security/security_connector.c b/src/core/security/security_connector.c
index f6e423eb27..726b4c1e12 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -653,9 +653,10 @@ grpc_security_status grpc_ssl_server_security_connector_create(
config->pem_private_keys_sizes,
(const unsigned char **)config->pem_cert_chains,
config->pem_cert_chains_sizes, config->num_key_cert_pairs,
- config->pem_root_certs, config->pem_root_certs_size, ssl_cipher_suites(),
- alpn_protocol_strings, alpn_protocol_string_lengths,
- (uint16_t)num_alpn_protocols, &c->handshaker_factory);
+ config->pem_root_certs, config->pem_root_certs_size,
+ config->force_client_auth, ssl_cipher_suites(), alpn_protocol_strings,
+ alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols,
+ &c->handshaker_factory);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index a4c723f026..2c9aa1c5a4 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -201,6 +201,7 @@ typedef struct {
size_t num_key_cert_pairs;
unsigned char *pem_root_certs;
size_t pem_root_certs_size;
+ int force_client_auth;
} grpc_ssl_server_config;
/* Creates an SSL server_security_connector.
diff --git a/src/core/support/stack_lockfree.c b/src/core/support/stack_lockfree.c
index 2844330379..f24e272207 100644
--- a/src/core/support/stack_lockfree.c
+++ b/src/core/support/stack_lockfree.c
@@ -72,6 +72,11 @@ typedef union lockfree_node {
struct gpr_stack_lockfree {
lockfree_node *entries;
lockfree_node head; /* An atomic entry describing curr head */
+
+#ifndef NDEBUG
+ /* Bitmap of pushed entries to check for double-push or pop */
+ gpr_atm pushed[(INVALID_ENTRY_INDEX+1)/(8*sizeof(gpr_atm))];
+#endif
};
gpr_stack_lockfree *gpr_stack_lockfree_create(int entries) {
@@ -86,6 +91,9 @@ gpr_stack_lockfree *gpr_stack_lockfree_create(int entries) {
/* Clear out all entries */
memset(stack->entries, 0, entries * sizeof(stack->entries[0]));
memset(&stack->head, 0, sizeof(stack->head));
+#ifndef NDEBUG
+ memset(&stack->pushed, 0, sizeof(stack->pushed));
+#endif
/* Point the head at reserved dummy entry */
stack->head.contents.index = INVALID_ENTRY_INDEX;
@@ -106,6 +114,19 @@ int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) {
/* Also post-increment the aba_ctr */
newhead.contents.aba_ctr = stack->entries[entry].contents.aba_ctr++;
+#ifndef NDEBUG
+ /* Check for double push */
+ {
+ int pushed_index = entry / (8*sizeof(gpr_atm));
+ int pushed_bit = entry % (8*sizeof(gpr_atm));
+ gpr_atm old_val;
+
+ old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
+ (gpr_atm)(1UL << pushed_bit));
+ GPR_ASSERT((old_val & (1UL<<pushed_bit)) == 0);
+ }
+#endif
+
do {
/* Atomically get the existing head value for use */
head.atm = gpr_atm_no_barrier_load(&(stack->head.atm));
@@ -119,6 +140,7 @@ int gpr_stack_lockfree_push(gpr_stack_lockfree *stack, int entry) {
int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) {
lockfree_node head;
lockfree_node newhead;
+
do {
head.atm = gpr_atm_acq_load(&(stack->head.atm));
if (head.contents.index == INVALID_ENTRY_INDEX) {
@@ -128,5 +150,18 @@ int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack) {
gpr_atm_no_barrier_load(&(stack->entries[head.contents.index].atm));
} while (!gpr_atm_no_barrier_cas(&(stack->head.atm), head.atm, newhead.atm));
+#ifndef NDEBUG
+ /* Check for valid pop */
+ {
+ int pushed_index = head.contents.index / (8*sizeof(gpr_atm));
+ int pushed_bit = head.contents.index % (8*sizeof(gpr_atm));
+ gpr_atm old_val;
+
+ old_val = gpr_atm_no_barrier_fetch_add(&stack->pushed[pushed_index],
+ -(gpr_atm)(1UL << pushed_bit));
+ GPR_ASSERT((old_val & (1UL<<pushed_bit)) != 0);
+ }
+#endif
+
return head.contents.index;
}
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index aefcbad244..12378f0066 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -932,7 +932,7 @@ static int prepare_application_metadata(grpc_call *call, size_t count,
GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
l->md = grpc_mdelem_from_string_and_buffer(call->metadata_context, md->key,
(const gpr_uint8 *)md->value,
- md->value_length);
+ md->value_length, 1);
if (!grpc_mdstr_is_legal_header(l->md->key)) {
gpr_log(GPR_ERROR, "attempt to send invalid metadata key");
return 0;
@@ -1203,7 +1203,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *c,
static grpc_call_error cancel_with_status(grpc_call *c, grpc_status_code status,
const char *description) {
grpc_mdstr *details =
- description ? grpc_mdstr_from_string(c->metadata_context, description)
+ description ? grpc_mdstr_from_string(c->metadata_context, description, 0)
: NULL;
GPR_ASSERT(status != GRPC_STATUS_OK);
@@ -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) {
@@ -1496,7 +1497,7 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
op->data.send_status_from_server.status_details != NULL
? grpc_mdstr_from_string(
call->metadata_context,
- op->data.send_status_from_server.status_details)
+ op->data.send_status_from_server.status_details, 0)
: NULL;
req = &reqs[out++];
req->op = GRPC_IOREQ_SEND_CLOSE;
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index 4052c65cc6..583d350128 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -101,19 +101,19 @@ grpc_channel *grpc_channel_create_from_filters(
/* decremented by grpc_channel_destroy */
gpr_ref_init(&channel->refs, 1);
channel->metadata_context = mdctx;
- channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status");
+ channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status", 0);
channel->grpc_compression_algorithm_string =
- grpc_mdstr_from_string(mdctx, "grpc-encoding");
- channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message");
+ grpc_mdstr_from_string(mdctx, "grpc-encoding", 0);
+ channel->grpc_message_string = grpc_mdstr_from_string(mdctx, "grpc-message", 0);
for (i = 0; i < NUM_CACHED_STATUS_ELEMS; i++) {
char buf[GPR_LTOA_MIN_BUFSIZE];
gpr_ltoa(i, buf);
channel->grpc_status_elem[i] = grpc_mdelem_from_metadata_strings(
mdctx, GRPC_MDSTR_REF(channel->grpc_status_string),
- grpc_mdstr_from_string(mdctx, buf));
+ grpc_mdstr_from_string(mdctx, buf, 0));
}
- channel->path_string = grpc_mdstr_from_string(mdctx, ":path");
- channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority");
+ channel->path_string = grpc_mdstr_from_string(mdctx, ":path", 0);
+ channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority", 0);
gpr_mu_init(&channel->registered_call_mu);
channel->registered_calls = NULL;
@@ -167,10 +167,10 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel,
channel, cq,
grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
- grpc_mdstr_from_string(channel->metadata_context, method)),
+ grpc_mdstr_from_string(channel->metadata_context, method, 0)),
grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->authority_string),
- grpc_mdstr_from_string(channel->metadata_context, host)),
+ grpc_mdstr_from_string(channel->metadata_context, host, 0)),
deadline);
}
@@ -179,10 +179,10 @@ void *grpc_channel_register_call(grpc_channel *channel, const char *method,
registered_call *rc = gpr_malloc(sizeof(registered_call));
rc->path = grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->path_string),
- grpc_mdstr_from_string(channel->metadata_context, method));
+ grpc_mdstr_from_string(channel->metadata_context, method, 0));
rc->authority = grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->authority_string),
- grpc_mdstr_from_string(channel->metadata_context, host));
+ grpc_mdstr_from_string(channel->metadata_context, host, 0));
gpr_mu_lock(&channel->registered_call_mu);
rc->next = channel->registered_calls;
channel->registered_calls = rc;
@@ -284,7 +284,7 @@ grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
gpr_ltoa(i, tmp);
return grpc_mdelem_from_metadata_strings(
channel->metadata_context, GRPC_MDSTR_REF(channel->grpc_status_string),
- grpc_mdstr_from_string(channel->metadata_context, tmp));
+ grpc_mdstr_from_string(channel->metadata_context, tmp, 0));
}
}
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
index fdc2185e14..707d615688 100644
--- a/src/core/surface/channel_create.c
+++ b/src/core/surface/channel_create.c
@@ -154,8 +154,8 @@ static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
Asynchronously: - resolve target
- connect to it (trying alternatives as presented)
- perform handshakes */
-grpc_channel *grpc_channel_create(const char *target,
- const grpc_channel_args *args) {
+grpc_channel *grpc_insecure_channel_create(const char *target,
+ const grpc_channel_args *args) {
grpc_channel *channel = NULL;
#define MAX_FILTERS 3
const grpc_channel_filter *filters[MAX_FILTERS];
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 24f35298ef..f19bcbd090 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;
@@ -677,8 +688,8 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master,
GPR_ASSERT(!is_last);
chand->server = NULL;
chand->channel = NULL;
- chand->path_key = grpc_mdstr_from_string(metadata_context, ":path");
- chand->authority_key = grpc_mdstr_from_string(metadata_context, ":authority");
+ chand->path_key = grpc_mdstr_from_string(metadata_context, ":path", 0);
+ chand->authority_key = grpc_mdstr_from_string(metadata_context, ":authority", 0);
chand->next = chand->prev = chand;
chand->registered_methods = NULL;
chand->connectivity_state = GRPC_CHANNEL_IDLE;
@@ -900,8 +911,8 @@ void grpc_server_setup_transport(grpc_server *s, grpc_transport *transport,
chand->registered_methods = gpr_malloc(alloc);
memset(chand->registered_methods, 0, alloc);
for (rm = s->registered_methods; rm; rm = rm->next) {
- host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host) : NULL;
- method = grpc_mdstr_from_string(mdctx, rm->method);
+ host = rm->host ? grpc_mdstr_from_string(mdctx, rm->host, 0) : NULL;
+ method = grpc_mdstr_from_string(mdctx, rm->method, 0);
hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
.server_registered_method != NULL;
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_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 65b31a5afd..0f04169741 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -441,7 +441,7 @@ static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline,
gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str);
mdelem = grpc_mdelem_from_metadata_strings(
c->mdctx, GRPC_MDSTR_REF(c->timeout_key_str),
- grpc_mdstr_from_string(c->mdctx, timeout_str));
+ grpc_mdstr_from_string(c->mdctx, timeout_str, 0));
mdelem = hpack_enc(c, mdelem, st);
if (mdelem) GRPC_MDELEM_UNREF(mdelem);
}
@@ -456,7 +456,7 @@ void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
grpc_mdctx *ctx) {
memset(c, 0, sizeof(*c));
c->mdctx = ctx;
- c->timeout_key_str = grpc_mdstr_from_string(ctx, "grpc-timeout");
+ c->timeout_key_str = grpc_mdstr_from_string(ctx, "grpc-timeout", 0);
}
void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
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..1ea4a82c16 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -232,7 +232,7 @@ static void init_transport(grpc_chttp2_transport *t,
t->global.pings.next = t->global.pings.prev = &t->global.pings;
t->parsing.is_client = is_client;
t->parsing.str_grpc_timeout =
- grpc_mdstr_from_string(t->metadata_context, "grpc-timeout");
+ grpc_mdstr_from_string(t->metadata_context, "grpc-timeout", 0);
t->parsing.deframe_state =
is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
t->writing.is_client = is_client;
@@ -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/metadata.c b/src/core/transport/metadata.c
index e95b7a21f9..967fd4898c 100644
--- a/src/core/transport/metadata.c
+++ b/src/core/transport/metadata.c
@@ -309,7 +309,37 @@ static void slice_unref(void *p) {
unlock(ctx);
}
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str) {
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str, int canonicalize_key) {
+ if (canonicalize_key) {
+ size_t len;
+ size_t i;
+ int canonical = 1;
+
+ for (i = 0; str[i]; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ canonical = 0;
+ /* Keep going in loop just to get string length */
+ }
+ }
+ len = i;
+
+ if (canonical) {
+ return grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)str, len);
+ } else {
+ char *copy = gpr_malloc(len);
+ grpc_mdstr *ret;
+ for (i = 0; i < len; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ copy[i] = str[i] - 'A' + 'a';
+ } else {
+ copy[i] = str[i];
+ }
+ }
+ ret = grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)copy, len);
+ gpr_free(copy);
+ return ret;
+ }
+ }
return grpc_mdstr_from_buffer(ctx, (const gpr_uint8 *)str, strlen(str));
}
@@ -491,8 +521,8 @@ grpc_mdelem *grpc_mdelem_from_metadata_strings(grpc_mdctx *ctx,
grpc_mdelem *grpc_mdelem_from_strings(grpc_mdctx *ctx, const char *key,
const char *value) {
return grpc_mdelem_from_metadata_strings(ctx,
- grpc_mdstr_from_string(ctx, key),
- grpc_mdstr_from_string(ctx, value));
+ grpc_mdstr_from_string(ctx, key, 0),
+ grpc_mdstr_from_string(ctx, value, 0));
}
grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
@@ -504,9 +534,10 @@ grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
const char *key,
const gpr_uint8 *value,
- size_t value_length) {
+ size_t value_length,
+ int canonicalize_key) {
return grpc_mdelem_from_metadata_strings(
- ctx, grpc_mdstr_from_string(ctx, key),
+ ctx, grpc_mdstr_from_string(ctx, key, canonicalize_key),
grpc_mdstr_from_buffer(ctx, value, value_length));
}
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index 99b15322c3..15ef9bb555 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -95,7 +95,7 @@ size_t grpc_mdctx_get_mdtab_free_test_only(grpc_mdctx *mdctx);
/* Constructors for grpc_mdstr instances; take a variety of data types that
clients may have handy */
-grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str);
+grpc_mdstr *grpc_mdstr_from_string(grpc_mdctx *ctx, const char *str, int perform_key_canonicalization);
/* Unrefs the slice. */
grpc_mdstr *grpc_mdstr_from_slice(grpc_mdctx *ctx, gpr_slice slice);
grpc_mdstr *grpc_mdstr_from_buffer(grpc_mdctx *ctx, const gpr_uint8 *str,
@@ -117,7 +117,8 @@ grpc_mdelem *grpc_mdelem_from_slices(grpc_mdctx *ctx, gpr_slice key,
grpc_mdelem *grpc_mdelem_from_string_and_buffer(grpc_mdctx *ctx,
const char *key,
const gpr_uint8 *value,
- size_t value_length);
+ size_t value_length,
+ int canonicalize_key);
/* Mutator and accessor for grpc_mdelem user data. The destructor function
is used as a type tag and is checked during user_data fetch. */
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/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index 6156a39d09..609fc06ed5 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -1293,8 +1293,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
const size_t* pem_private_keys_sizes, const unsigned char** pem_cert_chains,
const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count,
const unsigned char* pem_client_root_certs,
- size_t pem_client_root_certs_size, const char* cipher_list,
- const unsigned char** alpn_protocols,
+ size_t pem_client_root_certs_size, int force_client_auth,
+ const char* cipher_list, const unsigned char** alpn_protocols,
const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols,
tsi_ssl_handshaker_factory** factory) {
tsi_ssl_server_handshaker_factory* impl = NULL;
@@ -1349,6 +1349,7 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
if (result != TSI_OK) break;
if (pem_client_root_certs != NULL) {
+ int flags = SSL_VERIFY_PEER;
STACK_OF(X509_NAME)* root_names = NULL;
result = ssl_ctx_load_verification_certs(
impl->ssl_contexts[i], pem_client_root_certs,
@@ -1358,7 +1359,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
break;
}
SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names);
- SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, NULL);
+ if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL);
/* TODO(jboeuf): Add revocation verification. */
}
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index b2aa2f393e..4bf6c81b75 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -107,10 +107,14 @@ tsi_result tsi_create_ssl_client_handshaker_factory(
- key_cert_pair_count indicates the number of items in the private_key_files
and cert_chain_files parameters.
- pem_client_roots is the buffer containing the PEM encoding of the client
- root certificates. This parameter may be NULL in which case the server
- will not ask the client to authenticate itself with a certificate (server-
- only authentication mode).
- - pem_client_roots_size is the size of the associated buffer.
+ root certificates. This parameter may be NULL in which case the server will
+ not authenticate the client. If not NULL, the force_client_auth parameter
+ specifies if the server will accept only authenticated clients or both
+ authenticated and non-authenticated clients.
+ - pem_client_root_certs_size is the size of the associated buffer.
+ - force_client_auth, if set to non-zero will force the client to authenticate
+ with an SSL cert. Note that this option is ignored if pem_client_root_certs
+ is NULL or pem_client_roots_certs_size is 0
- cipher_suites contains an optional list of the ciphers that the server
supports. The format of this string is described in:
https://www.openssl.org/docs/apps/ciphers.html.
@@ -131,8 +135,8 @@ tsi_result tsi_create_ssl_server_handshaker_factory(
const size_t* pem_private_keys_sizes, const unsigned char** pem_cert_chains,
const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count,
const unsigned char* pem_client_root_certs,
- size_t pem_client_root_certs_size, const char* cipher_suites,
- const unsigned char** alpn_protocols,
+ size_t pem_client_root_certs_size, int force_client_auth,
+ const char* cipher_suites, const unsigned char** alpn_protocols,
const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols,
tsi_ssl_handshaker_factory** factory);
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index 5ad8784567..e802fa8034 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -49,7 +49,7 @@ class InsecureCredentialsImpl GRPC_FINAL : public Credentials {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
return std::shared_ptr<ChannelInterface>(new Channel(
- target, grpc_channel_create(target.c_str(), &channel_args)));
+ target, grpc_insecure_channel_create(target.c_str(), &channel_args)));
}
// InsecureCredentials should not be applied to a call.
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/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index 3e262dd74f..32c45e2280 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -51,7 +51,8 @@ std::shared_ptr<ServerCredentials> SslServerCredentials(
}
grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create(
options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
- &pem_key_cert_pairs[0], pem_key_cert_pairs.size());
+ &pem_key_cert_pairs[0], pem_key_cert_pairs.size(),
+ options.force_client_auth);
return std::shared_ptr<ServerCredentials>(
new SecureServerCredentials(c_creds));
}
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..8e5036832d 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>
@@ -23,25 +24,37 @@
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>full</DebugType>
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
<ItemGroup>
<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 +65,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>
@@ -73,7 +88,7 @@
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="GoogleCredential.cs" />
- <Compile Include="OAuth2InterceptorFactory.cs" />
+ <Compile Include="OAuth2Interceptors.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@@ -87,9 +102,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..2dc10d24c2 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
@@ -15,15 +15,14 @@
<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>
<files>
- <file src="bin/Release/Grpc.Auth.dll" target="lib/net45" />
- <file src="bin/Release/Grpc.Auth.pdb" target="lib/net45" />
- <file src="bin/Release/Grpc.Auth.xml" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.Auth.dll" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.Auth.pdb" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.Auth.xml" target="lib/net45" />
<file src="**\*.cs" target="src" />
</files>
</package>
diff --git a/src/csharp/Grpc.Auth/OAuth2InterceptorFactory.cs b/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
index 420c4cb537..c785ca5a16 100644
--- a/src/csharp/Grpc.Auth/OAuth2InterceptorFactory.cs
+++ b/src/csharp/Grpc.Auth/OAuth2Interceptors.cs
@@ -47,18 +47,32 @@ using Grpc.Core.Utils;
namespace Grpc.Auth
{
- public static class OAuth2InterceptorFactory
+ public static class OAuth2Interceptors
{
/// <summary>
- /// Creates OAuth2 interceptor.
+ /// Creates OAuth2 interceptor that will obtain access token from GoogleCredentials.
/// </summary>
- public static MetadataInterceptorDelegate Create(GoogleCredential googleCredential)
+ public static MetadataInterceptorDelegate FromCredential(GoogleCredential googleCredential)
{
var interceptor = new OAuth2Interceptor(googleCredential.InternalCredential, SystemClock.Default);
return new MetadataInterceptorDelegate(interceptor.InterceptHeaders);
}
/// <summary>
+ /// Creates OAuth2 interceptor that will use given OAuth2 token.
+ /// </summary>
+ /// <param name="oauth2Token"></param>
+ /// <returns></returns>
+ public static MetadataInterceptorDelegate FromAccessToken(string oauth2Token)
+ {
+ Preconditions.CheckNotNull(oauth2Token);
+ return new MetadataInterceptorDelegate((metadata) =>
+ {
+ metadata.Add(OAuth2Interceptor.CreateBearerTokenHeader(oauth2Token));
+ });
+ }
+
+ /// <summary>
/// Injects OAuth2 authorization header into initial metadata (= request headers).
/// </summary>
private class OAuth2Interceptor
@@ -97,8 +111,15 @@ namespace Grpc.Auth
public void InterceptHeaders(Metadata metadata)
{
var accessToken = GetAccessToken(CancellationToken.None);
- metadata.Add(new Metadata.Entry(AuthorizationHeader, Schema + " " + accessToken));
+ metadata.Add(CreateBearerTokenHeader(accessToken));
+ }
+
+ public static Metadata.Entry CreateBearerTokenHeader(string accessToken)
+ {
+ return new Metadata.Entry(AuthorizationHeader, Schema + " " + accessToken);
}
}
+
+
}
}
diff --git a/src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs
index 70cb32d5b2..83396c546b 100644
--- a/src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Auth/Properties/AssemblyInfo.cs
@@ -9,5 +9,3 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("Google Inc. All rights reserved.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
-
-[assembly: InternalsVisibleTo("Grpc.Auth.Tests")]
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..540fe756c0 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]
@@ -218,8 +209,8 @@ namespace Grpc.Core.Tests
{
var headers = new Metadata
{
- new Metadata.Entry("asciiHeader", "abcdefg"),
- new Metadata.Entry("binaryHeader-bin", new byte[] { 1, 2, 3, 0, 0xff }),
+ new Metadata.Entry("ascii-header", "abcdefg"),
+ new Metadata.Entry("binary-header-bin", new byte[] { 1, 2, 3, 0, 0xff }),
};
var internalCall = new Call<string, string>(ServiceName, EchoMethod, channel, headers);
var call = Calls.AsyncUnaryCall(internalCall, "ABC", CancellationToken.None);
@@ -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..242a60d098 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -17,20 +17,43 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>full</DebugType>
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</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 +67,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 +85,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..940a6b8ac0 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -21,15 +21,23 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>full</DebugType>
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <DefineConstants>SIGNED</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -47,7 +55,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 +110,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 +145,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/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec
index 5ace6dcf89..086776f69d 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.nuspec
+++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec
@@ -21,9 +21,9 @@
</dependencies>
</metadata>
<files>
- <file src="bin/Release/Grpc.Core.dll" target="lib/net45" />
- <file src="bin/Release/Grpc.Core.pdb" target="lib/net45" />
- <file src="bin/Release/Grpc.Core.xml" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.Core.dll" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.Core.pdb" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.Core.xml" target="lib/net45" />
<file src="**\*.cs" target="src" />
</files>
</package>
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/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
index 2b3d7530f2..29db85d7aa 100644
--- a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
+++ b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs
@@ -10,4 +10,12 @@ using System.Runtime.CompilerServices;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
+#if SIGNED
+[assembly: InternalsVisibleTo("Grpc.Core.Tests,PublicKey=" +
+ "00240000048000009400000006020000002400005253413100040000010001002f5797a92c6fcde81bd4098f43" +
+ "0442bb8e12768722de0b0cb1b15e955b32a11352740ee59f2c94c48edc8e177d1052536b8ac651bce11ce5da3a" +
+ "27fc95aff3dc604a6971417453f9483c7b5e836756d5b271bf8f2403fe186e31956148c03d804487cf642f8cc0" +
+ "71394ee9672dfe5b55ea0f95dfd5a7f77d22c962ccf51320d3")]
+#else
[assembly: InternalsVisibleTo("Grpc.Core.Tests")]
+#endif \ No newline at end of file
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..b603e3af3c 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>
@@ -19,17 +19,22 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <DebugType>full</DebugType>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</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..5f74b58773 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>
@@ -19,17 +19,22 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <DebugType>full</DebugType>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</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/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
index d59d7515d1..9a8f780b24 100644
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -19,15 +19,22 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>full</DebugType>
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework">
diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
index 7a957c5b6f..242d29a9a5 100644
--- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
+++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs
@@ -56,16 +56,16 @@ 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
// for header support.
client.HeaderInterceptor = (metadata) =>
{
- metadata.Add(new Metadata.Entry("customHeader", "abcdef"));
+ metadata.Add(new Metadata.Entry("custom-header", "abcdef"));
};
}
@@ -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/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
index eaf24a253c..c1aa40500e 100644
--- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj
+++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
@@ -19,15 +19,22 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>full</DebugType>
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
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/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
index 72e110302b..c922ddfb9e 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
+++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
@@ -17,7 +17,6 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -25,10 +24,18 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Google.ProtocolBuffers">
<HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll</HintPath>
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/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
index 4ebb6446dd..0b7a7b91c6 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
@@ -18,7 +18,6 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -26,10 +25,18 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
<ItemGroup>
<Reference Include="Google.ProtocolBuffers">
<HintPath>..\packages\Google.ProtocolBuffers.2.4.1.555\lib\net40\Google.ProtocolBuffers.dll</HintPath>
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
index ca35b36805..acdfba42c8 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec
@@ -20,9 +20,9 @@
</dependencies>
</metadata>
<files>
- <file src="bin/Release/Grpc.HealthCheck.dll" target="lib/net45" />
- <file src="bin/Release/Grpc.HealthCheck.pdb" target="lib/net45" />
- <file src="bin/Release/Grpc.HealthCheck.xml" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.HealthCheck.dll" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.HealthCheck.pdb" target="lib/net45" />
+ <file src="bin/ReleaseSigned/Grpc.HealthCheck.xml" target="lib/net45" />
<file src="**\*.cs" target="src" />
</files>
</package>
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..2c38c9645c 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>
@@ -18,17 +18,24 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <DebugType>full</DebugType>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</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..949ad61375 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>
@@ -18,17 +18,24 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <DebugType>full</DebugType>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</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..abc27f811e 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>
@@ -19,46 +18,44 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
- <DebugType>full</DebugType>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <Externalconsole>true</Externalconsole>
- <PlatformTarget>x86</PlatformTarget>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\ReleaseSigned</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
</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 Include="BouncyCastle.Crypto">
+ <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.1.12399, Culture=neutral, processorArchitecture=MSIL">
+ <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.1\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+ <HintPath>..\packages\Google.Apis.Auth.1.9.2\lib\net40\Google.Apis.Auth.dll</HintPath>
</Reference>
- <Reference Include="Google.Apis.Core, Version=1.9.1.12394, Culture=neutral, processorArchitecture=MSIL">
+ <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.2.27820, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, 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>
- <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, 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 +64,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 +104,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 +139,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..7411d91d5a 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -127,15 +127,15 @@ namespace Grpc.IntegrationTesting
{
credential = credential.CreateScoped(new[] { AuthScope });
}
- client.HeaderInterceptor = OAuth2InterceptorFactory.Create(credential);
+ client.HeaderInterceptor = OAuth2Interceptors.FromCredential(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)
@@ -368,11 +356,7 @@ namespace Grpc.IntegrationTesting
Assert.IsTrue(credential.RequestAccessTokenAsync(CancellationToken.None).Result);
string oauth2Token = credential.Token.AccessToken;
- // Intercept calls with an OAuth2 token obtained out-of-band.
- client.HeaderInterceptor = new MetadataInterceptorDelegate((metadata) =>
- {
- metadata.Add(new Metadata.Entry("Authorization", "Bearer " + oauth2Token));
- });
+ client.HeaderInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
var request = SimpleRequest.CreateBuilder()
.SetFillUsername(true)
@@ -393,78 +377,75 @@ namespace Grpc.IntegrationTesting
var credential = GoogleCredential.GetApplicationDefault().CreateScoped(new[] { AuthScope });
Assert.IsTrue(credential.RequestAccessTokenAsync(CancellationToken.None).Result);
string oauth2Token = credential.Token.AccessToken;
+ var headerInterceptor = OAuth2Interceptors.FromAccessToken(oauth2Token);
var request = SimpleRequest.CreateBuilder()
.SetFillUsername(true)
.SetFillOauthScope(true)
.Build();
- var response = client.UnaryCall(request, headers: new Metadata { new Metadata.Entry("Authorization", "Bearer " + oauth2Token) });
+ var headers = new Metadata();
+ headerInterceptor(headers);
+ var response = client.UnaryCall(request, headers: headers);
Assert.AreEqual(AuthScopeResponse, response.OauthScope);
Assert.AreEqual(ServiceAccountUser, response.Username);
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();
}
- Console.WriteLine("Passed!");
- }).Wait();
+ catch (RpcException e)
+ {
+ Assert.AreEqual(StatusCode.Cancelled, e.Status.StatusCode);
+ }
+ }
+ 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..f19f29c6a2 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -34,60 +34,83 @@ 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
+ ReleaseSigned|Any CPU = ReleaseSigned|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
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
+ {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
+ {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {7DC1433E-3225-42C7-B7EA-546D56E27A4B}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {86EC5CB4-4EA2-40A2-8057-86542A0353BB}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {C61154BA-DD4A-4838-8420-0162A28925E0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {C61154BA-DD4A-4838-8420-0162A28925E0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {3D166931-BA2D-416E-95A3-D36E8F6E90B9}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {A654F3B8-E859-4E6A-B30D-227527DBEF0D}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {BF62FE08-373A-43D6-9D73-41CAA38B7011}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {AA5E328A-8835-49D7-98ED-C29F2B3049F0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|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
+ {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU
+ {F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index c3e5fe8817..9e1253bf0b 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -12,7 +12,7 @@ cd ..\..\vsprojects\nuget_package
@call buildall.bat || goto :error
endlocal
-@call buildall.bat || goto :error
+@call buildall.bat BUILD_SIGNED || goto :error
%NUGET% pack ..\..\vsprojects\nuget_package\grpc.native.csharp_ext.nuspec -Version %CORE_VERSION% || goto :error
%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
diff --git a/src/csharp/buildall.bat b/src/csharp/buildall.bat
index 16860aec3c..e73feb87b9 100644
--- a/src/csharp/buildall.bat
+++ b/src/csharp/buildall.bat
@@ -13,6 +13,11 @@ msbuild ..\..\vsprojects\grpc.sln /t:grpc_csharp_ext /p:PlatformToolset=v120 ||
msbuild Grpc.sln /p:Configuration=Debug || goto :error
msbuild Grpc.sln /p:Configuration=Release || goto :error
+
+if "%1" == "BUILD_SIGNED" (
+msbuild Grpc.sln /p:Configuration=ReleaseSigned || goto :error
+)
+
endlocal
goto :EOF
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index ae8186398a..49a0471042 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -366,8 +366,9 @@ 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) {
- return grpc_channel_create(target, args);
+
+grpcsharp_insecure_channel_create(const char *target, const grpc_channel_args *args) {
+ return grpc_insecure_channel_create(target, args);
}
GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_destroy(grpc_channel *channel) {
@@ -432,10 +433,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 +465,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 +714,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);
}
@@ -772,8 +791,9 @@ grpcsharp_ssl_server_credentials_create(
key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i];
}
}
+ /* TODO: Add a force_client_auth parameter and pass it here. */
creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs,
- num_key_cert_pairs);
+ num_key_cert_pairs, 0);
gpr_free(key_cert_pairs);
return creds;
}
diff --git a/src/csharp/keys/Grpc.public.snk b/src/csharp/keys/Grpc.public.snk
new file mode 100644
index 0000000000..bac3046b36
--- /dev/null
+++ b/src/csharp/keys/Grpc.public.snk
Binary files differ
diff --git a/src/csharp/keys/README.md b/src/csharp/keys/README.md
new file mode 100644
index 0000000000..f3e9a3cb56
--- /dev/null
+++ b/src/csharp/keys/README.md
@@ -0,0 +1,5 @@
+Contents
+--------
+
+- Grpc.public.snk:
+ Public key to verify strong name of gRPC assemblies. \ No newline at end of file
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..c43b55f115 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);
@@ -103,7 +105,7 @@ NAN_METHOD(Channel::New) {
NanUtf8String *host = new NanUtf8String(args[0]);
NanUtf8String *host_override = NULL;
if (args[1]->IsUndefined()) {
- wrapped_channel = grpc_channel_create(**host, NULL);
+ wrapped_channel = grpc_insecure_channel_create(**host, NULL);
} else if (args[1]->IsObject()) {
grpc_credentials *creds = NULL;
Handle<Object> args_hash(args[1]->ToObject()->Clone());
@@ -148,7 +150,7 @@ NAN_METHOD(Channel::New) {
}
}
if (creds == NULL) {
- wrapped_channel = grpc_channel_create(**host, &channel_args);
+ wrapped_channel = grpc_insecure_channel_create(**host, &channel_args);
} else {
wrapped_channel =
grpc_secure_channel_create(creds, **host, &channel_args);
@@ -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..c4a93a6465 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);
}
@@ -140,14 +138,10 @@ NAN_METHOD(ServerCredentials::CreateSsl) {
return NanThrowTypeError("createSsl's third argument must be a Buffer");
}
key_cert_pair.cert_chain = ::node::Buffer::Data(args[2]);
+ // TODO Add a force_client_auth parameter and pass it as the last parameter
+ // here.
NanReturnValue(WrapStruct(
- 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()));
+ grpc_ssl_server_credentials_create(root_certs, &key_cert_pair, 1, 0)));
}
} // namespace node
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/index.js b/src/node/index.js
index d81e780443..b26ab35f2c 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -48,7 +48,7 @@ var grpc = require('bindings')('grpc');
* @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load.
* @return {Object<string, *>} The resulting gRPC object
*/
-function loadObject(value) {
+exports.loadObject = function loadObject(value) {
var result = {};
if (value.className === 'Namespace') {
_.each(value.children, function(child) {
@@ -62,7 +62,9 @@ function loadObject(value) {
} else {
return value;
}
-}
+};
+
+var loadObject = exports.loadObject;
/**
* Load a gRPC object from a .proto file.
@@ -71,7 +73,7 @@ function loadObject(value) {
* 'json'. Defaults to 'proto'
* @return {Object<string, *>} The resulting gRPC object
*/
-function load(filename, format) {
+exports.load = function load(filename, format) {
if (!format) {
format = 'proto';
}
@@ -88,7 +90,7 @@ function load(filename, format) {
}
return loadObject(builder.ns);
-}
+};
/**
* Get a function that a client can use to update metadata with authentication
@@ -97,7 +99,7 @@ function load(filename, format) {
* @param {Object} credential The credential object to use
* @return {function(Object, callback)} Metadata updater function
*/
-function getGoogleAuthDelegate(credential) {
+exports.getGoogleAuthDelegate = function getGoogleAuthDelegate(credential) {
/**
* Update a metadata object with authentication information.
* @param {string} authURI The uri to authenticate to
@@ -120,20 +122,10 @@ function getGoogleAuthDelegate(credential) {
callback(null, metadata);
});
};
-}
-
-/**
- * See docs for loadObject
- */
-exports.loadObject = loadObject;
+};
/**
- * See docs for load
- */
-exports.load = load;
-
-/**
- * See docs for Server
+ * @see module:src/server.Server
*/
exports.Server = server.Server;
@@ -141,6 +133,7 @@ exports.Server = server.Server;
* Status name to code number mapping
*/
exports.status = grpc.status;
+
/**
* Call error name to code number mapping
*/
@@ -156,6 +149,7 @@ exports.Credentials = grpc.Credentials;
*/
exports.ServerCredentials = grpc.ServerCredentials;
-exports.getGoogleAuthDelegate = getGoogleAuthDelegate;
-
+/**
+ * @see module:src/client.makeClientConstructor
+ */
exports.makeGenericClientConstructor = client.makeClientConstructor;
diff --git a/src/node/jsdoc_conf.json b/src/node/jsdoc_conf.json
new file mode 100644
index 0000000000..876a8e19c6
--- /dev/null
+++ b/src/node/jsdoc_conf.json
@@ -0,0 +1,22 @@
+{
+ "tags": {
+ "allowUnknownTags": true
+ },
+ "source": {
+ "include": [ "index.js", "src" ],
+ "includePattern": ".+\\.js(doc)?$",
+ "excludePattern": "(^|\\/|\\\\)_"
+ },
+ "opts": {
+ "package": "package.json",
+ "readme": "README.md"
+ },
+ "plugins": [],
+ "templates": {
+ "cleverLinks": false,
+ "monospaceLinks": false,
+ "default": {
+ "outputSourceFiles": true
+ }
+ }
+}
diff --git a/src/node/package.json b/src/node/package.json
index 1caf158792..756d41b0af 100644
--- a/src/node/package.json
+++ b/src/node/package.json
@@ -21,7 +21,8 @@
},
"scripts": {
"lint": "node ./node_modules/jshint/bin/jshint src test examples interop index.js",
- "test": "node ./node_modules/mocha/bin/mocha && npm run-script lint"
+ "test": "node ./node_modules/mocha/bin/mocha && npm run-script lint",
+ "gen_docs": "./node_modules/.bin/jsdoc -c jsdoc_conf.json"
},
"dependencies": {
"bindings": "^1.2.0",
@@ -32,6 +33,7 @@
"devDependencies": {
"async": "^0.9.0",
"google-auth-library": "^0.9.2",
+ "jsdoc": "^3.3.2",
"jshint": "^2.5.0",
"minimist": "^1.1.0",
"mocha": "~1.21.0",
diff --git a/src/node/src/client.js b/src/node/src/client.js
index da6327b432..f843669bd0 100644
--- a/src/node/src/client.js
+++ b/src/node/src/client.js
@@ -31,6 +31,11 @@
*
*/
+/**
+ * Server module
+ * @module
+ */
+
'use strict';
var _ = require('lodash');
@@ -72,6 +77,7 @@ function ClientWritableStream(call, serialize) {
/**
* Attempt to write the given chunk. Calls the callback when done. This is an
* implementation of a method needed for implementing stream.Writable.
+ * @access private
* @param {Buffer} chunk The chunk to write
* @param {string} encoding Ignored
* @param {function(Error=)} callback Called when the write is complete
@@ -110,6 +116,7 @@ function ClientReadableStream(call, deserialize) {
/**
* Read the next object from the stream.
+ * @access private
* @param {*} size Ignored because we use objectMode=true
*/
function _read(size) {
@@ -188,6 +195,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 +243,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();
@@ -503,7 +526,7 @@ var requester_makers = {
* @param {string} serviceName The name of the service
* @return {function(string, Object)} New client constructor
*/
-function makeClientConstructor(methods, serviceName) {
+exports.makeClientConstructor = function(methods, serviceName) {
/**
* Create a client with the given methods
* @constructor
@@ -552,7 +575,7 @@ function makeClientConstructor(methods, serviceName) {
});
return Client;
-}
+};
/**
* Creates a constructor for clients for the given service
@@ -560,22 +583,18 @@ function makeClientConstructor(methods, serviceName) {
* for
* @return {function(string, Object)} New client constructor
*/
-function makeProtobufClientConstructor(service) {
+exports.makeProtobufClientConstructor = function(service) {
var method_attrs = common.getProtobufServiceAttrs(service, service.name);
- var Client = makeClientConstructor(method_attrs);
+ var Client = exports.makeClientConstructor(method_attrs);
Client.service = service;
-
return Client;
-}
-
-exports.makeClientConstructor = makeClientConstructor;
-
-exports.makeProtobufClientConstructor = makeProtobufClientConstructor;
+};
/**
- * See docs for client.status
+ * Map of status code names to status codes
*/
exports.status = grpc.status;
+
/**
* See docs for client.callError
*/
diff --git a/src/node/src/common.js b/src/node/src/common.js
index feaa859a4f..5551ebeec8 100644
--- a/src/node/src/common.js
+++ b/src/node/src/common.js
@@ -31,6 +31,10 @@
*
*/
+/**
+ * @module
+ */
+
'use strict';
var _ = require('lodash');
@@ -40,7 +44,7 @@ var _ = require('lodash');
* @param {function()} cls The constructor of the message type to deserialize
* @return {function(Buffer):cls} The deserialization function
*/
-function deserializeCls(cls) {
+exports.deserializeCls = function deserializeCls(cls) {
/**
* Deserialize a buffer to a message object
* @param {Buffer} arg_buf The buffer to deserialize
@@ -51,14 +55,16 @@ function deserializeCls(cls) {
// and longs as strings (second argument)
return cls.decode(arg_buf).toRaw(false, true);
};
-}
+};
+
+var deserializeCls = exports.deserializeCls;
/**
* Get a function that serializes objects to a buffer by protobuf class.
* @param {function()} Cls The constructor of the message type to serialize
* @return {function(Cls):Buffer} The serialization function
*/
-function serializeCls(Cls) {
+exports.serializeCls = function serializeCls(Cls) {
/**
* Serialize an object to a Buffer
* @param {Object} arg The object to serialize
@@ -67,14 +73,16 @@ function serializeCls(Cls) {
return function serialize(arg) {
return new Buffer(new Cls(arg).encode().toBuffer());
};
-}
+};
+
+var serializeCls = exports.serializeCls;
/**
* Get the fully qualified (dotted) name of a ProtoBuf.Reflect value.
* @param {ProtoBuf.Reflect.Namespace} value The value to get the name of
* @return {string} The fully qualified name of the value
*/
-function fullyQualifiedName(value) {
+exports.fullyQualifiedName = function fullyQualifiedName(value) {
if (value === null || value === undefined) {
return '';
}
@@ -89,7 +97,9 @@ function fullyQualifiedName(value) {
}
}
return name;
-}
+};
+
+var fullyQualifiedName = exports.fullyQualifiedName;
/**
* Wrap a function to pass null-like values through without calling it. If no
@@ -97,7 +107,7 @@ function fullyQualifiedName(value) {
* @param {?function} func The function to wrap
* @return {function} The wrapped function
*/
-function wrapIgnoreNull(func) {
+exports.wrapIgnoreNull = function wrapIgnoreNull(func) {
if (!func) {
return _.identity;
}
@@ -107,14 +117,14 @@ function wrapIgnoreNull(func) {
}
return func(arg);
};
-}
+};
/**
* Return a map from method names to method attributes for the service.
* @param {ProtoBuf.Reflect.Service} service The service to get attributes for
* @return {Object} The attributes map
*/
-function getProtobufServiceAttrs(service) {
+exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service) {
var prefix = '/' + fullyQualifiedName(service) + '/';
return _.object(_.map(service.children, function(method) {
return [_.camelCase(method.name), {
@@ -127,26 +137,4 @@ function getProtobufServiceAttrs(service) {
responseDeserialize: deserializeCls(method.resolvedResponseType.build())
}];
}));
-}
-
-/**
- * See docs for deserializeCls
- */
-exports.deserializeCls = deserializeCls;
-
-/**
- * See docs for serializeCls
- */
-exports.serializeCls = serializeCls;
-
-/**
- * See docs for fullyQualifiedName
- */
-exports.fullyQualifiedName = fullyQualifiedName;
-
-/**
- * See docs for wrapIgnoreNull
- */
-exports.wrapIgnoreNull = wrapIgnoreNull;
-
-exports.getProtobufServiceAttrs = getProtobufServiceAttrs;
+};
diff --git a/src/node/src/server.js b/src/node/src/server.js
index 0a3a0031bd..9fbd1ee3bd 100644
--- a/src/node/src/server.js
+++ b/src/node/src/server.js
@@ -31,6 +31,11 @@
*
*/
+/**
+ * Server module
+ * @module
+ */
+
'use strict';
var _ = require('lodash');
@@ -50,6 +55,7 @@ var EventEmitter = require('events').EventEmitter;
/**
* Handle an error on a call by sending it as a status
+ * @access private
* @param {grpc.Call} call The call to send the error on
* @param {Object} error The error object
*/
@@ -82,6 +88,7 @@ function handleError(call, error) {
/**
* Wait for the client to close, then emit a cancelled event if the client
* cancelled.
+ * @access private
* @param {grpc.Call} call The call object to wait on
* @param {EventEmitter} emitter The event emitter to emit the cancelled event
* on
@@ -102,6 +109,7 @@ function waitForCancel(call, emitter) {
/**
* Send a response to a unary or client streaming call.
+ * @access private
* @param {grpc.Call} call The call to respond on
* @param {*} value The value to respond with
* @param {function(*):Buffer=} serialize Serialization function for the
@@ -130,6 +138,7 @@ function sendUnaryResponse(call, value, serialize, metadata) {
/**
* Initialize a writable stream. This is used for both the writable and duplex
* stream constructors.
+ * @access private
* @param {Writable} stream The stream to set up
* @param {function(*):Buffer=} Serialization function for responses
*/
@@ -203,6 +212,7 @@ function setUpWritable(stream, serialize) {
/**
* Initialize a readable stream. This is used for both the readable and duplex
* stream constructors.
+ * @access private
* @param {Readable} stream The stream to initialize
* @param {function(Buffer):*=} deserialize Deserialization function for
* incoming data.
@@ -242,6 +252,7 @@ function ServerWritableStream(call, serialize) {
/**
* Start writing a chunk of data. This is an implementation of a method required
* for implementing stream.Writable.
+ * @access private
* @param {Buffer} chunk The chunk of data to write
* @param {string} encoding Ignored
* @param {function(Error=)} callback Callback to indicate that the write is
@@ -266,6 +277,11 @@ function _write(chunk, encoding, callback) {
ServerWritableStream.prototype._write = _write;
+/**
+ * Send the initial metadata for a writable stream.
+ * @param {Object<String, Array<(String|Buffer)>>} responseMetadata Metadata
+ * to send
+ */
function sendMetadata(responseMetadata) {
/* jshint validthis: true */
if (!this.call.metadataSent) {
@@ -281,6 +297,10 @@ function sendMetadata(responseMetadata) {
}
}
+/**
+ * @inheritdoc
+ * @alias module:src/server~ServerWritableStream#sendMetadata
+ */
ServerWritableStream.prototype.sendMetadata = sendMetadata;
util.inherits(ServerReadableStream, Readable);
@@ -301,6 +321,7 @@ function ServerReadableStream(call, deserialize) {
/**
* Start reading from the gRPC data source. This is an implementation of a
* method required for implementing stream.Readable
+ * @access private
* @param {number} size Ignored
*/
function _read(size) {
@@ -374,7 +395,21 @@ 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
+ * @access private
* @param {grpc.Call} call The call to handle
* @param {Object} handler Request handler object for the method that was called
* @param {Object} metadata Metadata from the client
@@ -389,6 +424,9 @@ function handleUnary(call, handler, metadata) {
call.startBatch(batch, function() {});
}
};
+ emitter.getPeer = function() {
+ return call.getPeer();
+ };
emitter.on('error', function(error) {
handleError(call, error);
});
@@ -426,6 +464,7 @@ function handleUnary(call, handler, metadata) {
/**
* Fully handle a server streaming call
+ * @access private
* @param {grpc.Call} call The call to handle
* @param {Object} handler Request handler object for the method that was called
* @param {Object} metadata Metadata from the client
@@ -454,6 +493,7 @@ function handleServerStreaming(call, handler, metadata) {
/**
* Fully handle a client streaming call
+ * @access private
* @param {grpc.Call} call The call to handle
* @param {Object} handler Request handler object for the method that was called
* @param {Object} metadata Metadata from the client
@@ -488,6 +528,7 @@ function handleClientStreaming(call, handler, metadata) {
/**
* Fully handle a bidirectional streaming call
+ * @access private
* @param {grpc.Call} call The call to handle
* @param {Object} handler Request handler object for the method that was called
* @param {Object} metadata Metadata from the client
@@ -544,7 +585,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;
@@ -571,7 +612,8 @@ function Server(options) {
}
server.requestCall(handleNewCall);
};
- /** Shuts down the server.
+ /**
+ * Shuts down the server.
*/
this.shutdown = function() {
server.shutdown();
@@ -605,6 +647,15 @@ Server.prototype.register = function(name, handler, serialize, deserialize,
return true;
};
+/**
+ * Add a service to the server, with a corresponding implementation. If you are
+ * generating this from a proto file, you should instead use
+ * addProtoService.
+ * @param {Object<String, *>} service The service descriptor, as
+ * {@link module:src/common.getProtobufServiceAttrs} returns
+ * @param {Object<String, function>} implementation Map of method names to
+ * method implementation for the provided service.
+ */
Server.prototype.addService = function(service, implementation) {
if (this.started) {
throw new Error('Can\'t add a service to a started server.');
@@ -642,6 +693,12 @@ Server.prototype.addService = function(service, implementation) {
});
};
+/**
+ * Add a proto service to the server, with a corresponding implementation
+ * @param {Protobuf.Reflect.Service} service The proto service descriptor
+ * @param {Object<String, function>} implementation Map of method names to
+ * method implementation for the provided service.
+ */
Server.prototype.addProtoService = function(service, implementation) {
this.addService(common.getProtobufServiceAttrs(service), implementation);
};
@@ -665,6 +722,6 @@ Server.prototype.bind = function(port, creds) {
};
/**
- * See documentation for Server
+ * @see module:src/server~Server
*/
exports.Server = Server;
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/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m
index d27f7ca565..8518f78c5b 100644
--- a/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCUnsecuredChannel.m
@@ -38,7 +38,7 @@
@implementation GRPCUnsecuredChannel
- (instancetype)initWithHost:(NSString *)host {
- return (self = [super initWithChannel:grpc_channel_create(host.UTF8String, NULL)]);
+ return (self = [super initWithChannel:grpc_insecure_channel_create(host.UTF8String, NULL)]);
}
@end
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/call.c b/src/php/ext/grpc/call.c
index b67bae7568..1f76c7359d 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -473,6 +473,16 @@ cleanup:
}
/**
+ * Get the endpoint this call/stream is connected to
+ * @return string The URI of the endpoint
+ */
+PHP_METHOD(Call, getPeer) {
+ wrapped_grpc_call *call =
+ (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC);
+ RETURN_STRING(grpc_call_get_peer(call->wrapped), 1);
+}
+
+/**
* Cancel the call. This will cause the call to end with STATUS_CANCELLED if it
* has not already ended with another status.
*/
@@ -485,7 +495,9 @@ PHP_METHOD(Call, cancel) {
static zend_function_entry call_methods[] = {
PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC)
- PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
+ PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC)
+ PHP_FE_END};
void grpc_init_call(TSRMLS_D) {
zend_class_entry ce;
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index b8262db162..7d8a6f87ab 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -152,7 +152,7 @@ PHP_METHOD(Channel, __construct) {
override = target;
override_len = target_length;
if (args_array == NULL) {
- channel->wrapped = grpc_channel_create(target, NULL);
+ channel->wrapped = grpc_insecure_channel_create(target, NULL);
} else {
array_hash = Z_ARRVAL_P(args_array);
if (zend_hash_find(array_hash, "credentials", sizeof("credentials"),
@@ -182,7 +182,7 @@ PHP_METHOD(Channel, __construct) {
}
php_grpc_read_args_array(args_array, &args);
if (creds == NULL) {
- channel->wrapped = grpc_channel_create(target, &args);
+ channel->wrapped = grpc_insecure_channel_create(target, &args);
} else {
gpr_log(GPR_DEBUG, "Initialized secure channel");
channel->wrapped =
@@ -195,6 +195,16 @@ PHP_METHOD(Channel, __construct) {
}
/**
+ * Get the endpoint this call/stream is connected to
+ * @return string The URI of the endpoint
+ */
+PHP_METHOD(Channel, getTarget) {
+ wrapped_grpc_channel *channel =
+ (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC);
+ RETURN_STRING(grpc_channel_get_target(channel->wrapped), 1);
+}
+
+/**
* Close the channel
*/
PHP_METHOD(Channel, close) {
@@ -208,7 +218,9 @@ PHP_METHOD(Channel, close) {
static zend_function_entry channel_methods[] = {
PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
- PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) PHP_FE_END};
+ PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC)
+ PHP_FE_END};
void grpc_init_channel(TSRMLS_D) {
zend_class_entry ce;
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..e9183c4598 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -115,27 +115,16 @@ PHP_METHOD(ServerCredentials, createSsl) {
"createSsl expects 3 strings", 1 TSRMLS_CC);
return;
}
- grpc_server_credentials *creds =
- grpc_ssl_server_credentials_create(pem_root_certs, &pem_key_cert_pair, 1);
- zval *creds_object = grpc_php_wrap_server_credentials(creds);
- 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();
+ /* TODO: add a force_client_auth field in ServerCredentials and pass it as
+ * the last parameter. */
+ grpc_server_credentials *creds = grpc_ssl_server_credentials_create(
+ pem_root_certs, &pem_key_cert_pair, 1, 0);
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/AbstractCall.php b/src/php/lib/Grpc/AbstractCall.php
index 5b28417a0d..35057224f8 100644
--- a/src/php/lib/Grpc/AbstractCall.php
+++ b/src/php/lib/Grpc/AbstractCall.php
@@ -68,6 +68,13 @@ abstract class AbstractCall {
}
/**
+ * @return string The URI of the endpoint.
+ */
+ public function getPeer() {
+ return $this->call->getPeer();
+ }
+
+ /**
* Cancels the call
*/
public function cancel() {
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index 48c00977eb..a0c677908c 100755
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -60,11 +60,21 @@ 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);
}
/**
+ * @return string The URI of the endpoint.
+ */
+ public function getTarget() {
+ return $this->channel->getTarget();
+ }
+
+ /**
* Close the communication channel associated with this stub
*/
public function close() {
diff --git a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
index 6102aaf0a8..8b7e67f57c 100644
--- a/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
+++ b/src/php/tests/generated_code/AbstractGeneratedCodeTest.php
@@ -43,7 +43,9 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase {
$div_arg = new math\DivArgs();
$div_arg->setDividend(7);
$div_arg->setDivisor(4);
- list($response, $status) = self::$client->Div($div_arg)->wait();
+ $call = self::$client->Div($div_arg);
+ $this->assertTrue(is_string($call->getPeer()));
+ list($response, $status) = $call->wait();
$this->assertSame(1, $response->getQuotient());
$this->assertSame(3, $response->getRemainder());
$this->assertSame(\Grpc\STATUS_OK, $status->code);
@@ -53,6 +55,7 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase {
$fib_arg = new math\FibArgs();
$fib_arg->setLimit(7);
$call = self::$client->Fib($fib_arg);
+ $this->assertTrue(is_string($call->getPeer()));
$result_array = iterator_to_array($call->responses());
$extract_num = function($num){
return $num->getNum();
@@ -72,6 +75,7 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase {
}
};
$call = self::$client->Sum($num_iter());
+ $this->assertTrue(is_string($call->getPeer()));
list($response, $status) = $call->wait();
$this->assertSame(21, $response->getNum());
$this->assertSame(\Grpc\STATUS_OK, $status->code);
@@ -79,6 +83,7 @@ abstract class AbstractGeneratedCodeTest extends PHPUnit_Framework_TestCase {
public function testBidiStreaming() {
$call = self::$client->DivMany();
+ $this->assertTrue(is_string($call->getPeer()));
for ($i = 0; $i < 7; $i++) {
$div_arg = new math\DivArgs();
$div_arg->setDividend(2 * $i + 1);
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 2041577557..44e6242c29 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -332,10 +332,11 @@ if (in_array($args['test_case'], array(
$opts['update_metadata'] = $auth->getUpdateMetadataFunc();
}
-$stub = new grpc\testing\TestServiceClient(
- new Grpc\BaseStub(
- $server_address,
- $opts));
+$internal_stub = new Grpc\BaseStub($server_address, $opts);
+hardAssert(is_string($internal_stub->getTarget()),
+ 'Unexpected target URI value');
+
+$stub = new grpc\testing\TestServiceClient($internal_stub);
echo "Connecting to $server_address\n";
echo "Running test case $args[test_case]\n";
diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php
index 77a2d86ce4..caff15ee11 100755
--- a/src/php/tests/unit_tests/CallTest.php
+++ b/src/php/tests/unit_tests/CallTest.php
@@ -79,4 +79,8 @@ class CallTest extends PHPUnit_Framework_TestCase{
$result = $this->call->startBatch($batch);
$this->assertTrue($result->send_metadata);
}
+
+ public function testGetPeer() {
+ $this->assertTrue(is_string($this->call->getPeer()));
+ }
}
diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php
index 2980dca4a7..27e27cdfdf 100755
--- a/src/php/tests/unit_tests/EndToEndTest.php
+++ b/src/php/tests/unit_tests/EndToEndTest.php
@@ -34,8 +34,8 @@
class EndToEndTest extends PHPUnit_Framework_TestCase{
public function setUp() {
$this->server = new Grpc\Server([]);
- $port = $this->server->addHttp2Port('0.0.0.0:0');
- $this->channel = new Grpc\Channel('localhost:' . $port, []);
+ $this->port = $this->server->addHttp2Port('0.0.0.0:0');
+ $this->channel = new Grpc\Channel('localhost:' . $this->port, []);
$this->server->start();
}
@@ -149,4 +149,8 @@ class EndToEndTest extends PHPUnit_Framework_TestCase{
unset($call);
unset($server_call);
}
+
+ public function testGetTarget() {
+ $this->assertTrue(is_string($this->channel->getTarget()));
+ }
}
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/channel.c b/src/python/src/grpc/_adapter/_c/types/channel.c
index c235597466..feb256cf00 100644
--- a/src/python/src/grpc/_adapter/_c/types/channel.c
+++ b/src/python/src/grpc/_adapter/_c/types/channel.c
@@ -104,7 +104,7 @@ Channel *pygrpc_Channel_new(
if (creds) {
self->c_chan = grpc_secure_channel_create(creds->c_creds, target, &c_args);
} else {
- self->c_chan = grpc_channel_create(target, &c_args);
+ self->c_chan = grpc_insecure_channel_create(target, &c_args);
}
pygrpc_discard_channel_args(c_args);
return self;
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..f6859b79d7 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[] = "";
@@ -131,16 +128,11 @@ ServerCredentials *pygrpc_ServerCredentials_ssl(
}
self = (ServerCredentials *)type->tp_alloc(type, 0);
+ /* TODO: Add a force_client_auth parameter in the python object and pass it
+ here as the last arg. */
self->c_creds = grpc_ssl_server_credentials_create(
- root_certs, key_cert_pairs, num_key_cert_pairs);
+ root_certs, key_cert_pairs, num_key_cert_pairs, 0);
gpr_free(key_cert_pairs);
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/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py
index a49cd007bf..9a8edfad0c 100644
--- a/src/python/src/grpc/_adapter/_low_test.py
+++ b/src/python/src/grpc/_adapter/_low_test.py
@@ -97,7 +97,7 @@ class InsecureServerInsecureClient(unittest.TestCase):
CLIENT_METADATA_BIN_VALUE = b'\0'*1000
SERVER_INITIAL_METADATA_KEY = 'init_me_me_me'
SERVER_INITIAL_METADATA_VALUE = 'whodawha?'
- SERVER_TRAILING_METADATA_KEY = 'California_is_in_a_drought'
+ SERVER_TRAILING_METADATA_KEY = 'california_is_in_a_drought'
SERVER_TRAILING_METADATA_VALUE = 'zomg it is'
SERVER_STATUS_CODE = _types.StatusCode.OK
SERVER_STATUS_DETAILS = 'our work is never over'
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/python/src/grpc/_links/_proto_scenarios.py b/src/python/src/grpc/_links/_proto_scenarios.py
index ccf3c29782..320c0e0f50 100644
--- a/src/python/src/grpc/_links/_proto_scenarios.py
+++ b/src/python/src/grpc/_links/_proto_scenarios.py
@@ -33,6 +33,7 @@ import abc
import threading
from grpc._junkdrawer import math_pb2
+from grpc.framework.common import test_constants
class ProtoScenario(object):
@@ -219,10 +220,9 @@ class BidirectionallyUnaryScenario(ProtoScenario):
class BidirectionallyStreamingScenario(ProtoScenario):
"""A scenario that transmits no protocol buffers in either direction."""
- _STREAM_LENGTH = 200
_REQUESTS = tuple(
math_pb2.DivArgs(dividend=59 + index, divisor=7 + index)
- for index in range(_STREAM_LENGTH))
+ for index in range(test_constants.STREAM_LENGTH))
def __init__(self):
self._lock = threading.Lock()
diff --git a/src/python/src/grpc/framework/common/test_constants.py b/src/python/src/grpc/framework/common/test_constants.py
index 237b8754ed..3126d0d82c 100644
--- a/src/python/src/grpc/framework/common/test_constants.py
+++ b/src/python/src/grpc/framework/common/test_constants.py
@@ -35,3 +35,9 @@ SHORT_TIMEOUT = 4
# Absurdly large value for maximum duration in seconds for should-not-time-out
# RPCs made during tests.
LONG_TIMEOUT = 3000
+
+# The number of payloads to transmit in streaming tests.
+STREAM_LENGTH = 200
+
+# The size of thread pools to use in tests.
+POOL_SIZE = 10
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index bfb9f6ff01..a7607a83a3 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -235,8 +235,8 @@ static VALUE grpc_rb_call_set_metadata(VALUE self, VALUE metadata) {
*/
static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
grpc_metadata_array *md_ary = NULL;
- int array_length;
- int i;
+ long array_length;
+ long i;
/* Construct a metadata object from key and value and add it */
TypedData_Get_Struct(md_ary_obj, grpc_metadata_array,
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index 9bf1a9f945..0cb6fa2f80 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -146,7 +146,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
target_chars = StringValueCStr(target);
grpc_rb_hash_convert_to_channel_args(channel_args, &args);
if (credentials == Qnil) {
- ch = grpc_channel_create(target_chars, &args);
+ ch = grpc_insecure_channel_create(target_chars, &args);
} else {
creds = grpc_rb_get_wrapped_credentials(credentials);
ch = grpc_secure_channel_create(creds, target_chars, &args);
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 829f825597..327fd1a4fc 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -139,7 +139,7 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) {
rb_raise(rb_eRangeError, "%f out of Time range",
RFLOAT_VALUE(time));
}
- t.tv_nsec = (time_t)(d * 1e9 + 0.5);
+ t.tv_nsec = (int)(d * 1e9 + 0.5);
}
break;
@@ -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/src/ruby/ext/grpc/rb_server_credentials.c b/src/ruby/ext/grpc/rb_server_credentials.c
index 5f40935890..62c211d769 100644
--- a/src/ruby/ext/grpc/rb_server_credentials.c
+++ b/src/ruby/ext/grpc/rb_server_credentials.c
@@ -176,11 +176,12 @@ static VALUE grpc_rb_server_credentials_init(VALUE self, VALUE pem_root_certs,
}
key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
+ /* TODO Add a force_client_auth parameter and pass it here. */
if (pem_root_certs == Qnil) {
- creds = grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1);
+ creds = grpc_ssl_server_credentials_create(NULL, &key_cert_pair, 1, 0);
} else {
creds = grpc_ssl_server_credentials_create(RSTRING_PTR(pem_root_certs),
- &key_cert_pair, 1);
+ &key_cert_pair, 1, 0);
}
if (creds == NULL) {
rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
diff --git a/templates/vsprojects/Grpc.mak.template b/templates/vsprojects/Grpc.mak.template
index 9d85376648..9d2f676d38 100644
--- a/templates/vsprojects/Grpc.mak.template
+++ b/templates/vsprojects/Grpc.mak.template
@@ -33,16 +33,18 @@
<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\
<%
build_from_project_file = set(['gpr',
- 'grpc',
- 'grpc_unsecure',
'gpr_test_util',
+ 'grpc',
'grpc_test_util',
'grpc_test_util_unsecure',
+ 'grpc_unsecure',
+ 'grpc++',
+ 'grpc++_unsecure'
])
buildable_targets = [ target for target in targets + libs
if target.build in ['all', 'test', 'private', 'tool', 'benchmark'] and
target.language in ['c', 'c++'] and
- all([src.endswith('.c') for src in target.src]) and
+ all([(src.endswith('.c') or src.endswith('.cc') or src.endswith('.proto')) for src in target.src]) and
'windows' in target.get('platforms', ['windows']) ]
c_test_targets = [ target for target in buildable_targets if target.build == 'test' and not target.language == 'c++' ]
cxx_test_targets = [ target for target in buildable_targets if target.build == 'test' and target.language == 'c++' ]
@@ -60,8 +62,19 @@ REPO_ROOT=..
OPENSSL_INCLUDES = .\packages\${get_openssl()}\build\native\include
ZLIB_INCLUDES = .\packages\${get_zlib()}\build\native\include
INCLUDES=/I$(REPO_ROOT) /I$(REPO_ROOT)\include /I$(OPENSSL_INCLUDES) /I$(ZLIB_INCLUDES)
-DEFINES=/D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /D _CRT_SECURE_NO_WARNINGS
+
+GFLAGS_INCLUDES = .\..\third_party\gflags\include
+GTEST_INCLUDES = .\..\third_party\gtest\include
+PROTOBUF_INCLUDES = .\..\third_party\protobuf\src
+CXX_INCLUDES=/I$(GFLAGS_INCLUDES) /I$(GTEST_INCLUDES) /I$(PROTOBUF_INCLUDES)
+
+#_SCL_SECURE_NO_WARNINGS supresses a ton of "potentially unsafe use of std lib" warnings
+DEFINES=/D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /D _CRT_SECURE_NO_WARNINGS /D _SCL_SECURE_NO_WARNINGS
+
+#important options: /TC vs. /TP: compile as C vs. compile as C++
CFLAGS=/c $(INCLUDES) /Z7 /W3 /WX- /sdl $(DEFINES) /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze-
+CXXFLAGS=/c $(INCLUDES) $(CXX_INCLUDES) /Z7 /W3 /WX- /sdl $(DEFINES) /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TP /analyze-
+
LFLAGS=/DEBUG /INCREMENTAL /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86
OPENSSL_LIBS=.\packages\${get_openssl()}\build\native\lib\v120\Win32\Debug\static\ssleay32.lib .\packages\${get_openssl()}\build\native\lib\v120\Win32\Debug\static\libeay32.lib
@@ -70,6 +83,12 @@ GENERAL_LIBS=advapi32.lib comdlg32.lib gdi32.lib kernel32.lib odbc32.lib odbccp3
ZLIB_LIBS=.\packages\${get_zlib()}\build\native\lib\v120\Win32\Debug\static\cdecl\zlib.lib
LIBS=$(OPENSSL_LIBS) $(ZLIB_LIBS) $(GENERAL_LIBS) $(WINSOCK_LIBS)
+#shlwapi.lib provides PathMatchSpec() for gflags in windows
+GFLAGS_LIBS=.\..\third_party\gflags\lib\Debug\gflags.lib shlwapi.lib
+GTEST_LIBS=.\..\third_party\gtest\msvc\gtest\Debug\gtestd.lib
+PROTOBUF_LIBS=.\..\third_party\protobuf\vsprojects\Debug\libprotobuf.lib
+CXX_LIBS=$(GFLAGS_LIBS) $(GTEST_LIBS) $(PROTOBUF_LIBS)
+
all: buildtests
tools:
@@ -99,16 +118,33 @@ buildtests_c: \
${target.name}.exe \
% endfor
- echo All tests built.
+ echo All C tests built.
buildtests_cxx: \
% for target in cxx_test_targets:
${target.name}.exe \
% endfor
- echo All tests built.
+ echo All C++ tests built.
% for target in buildable_targets:
+
+## replace all .proto includes with .pb.cc / .grpc.pb.cc
+%if target.src:
+%for source in target.src:
+%if source.endswith(".proto"):
+<%
+ src_name_parts = source.split(".")
+ target.src.append(src_name_parts[0] + ".pb.cc")
+ target.src.append(src_name_parts[0] + ".grpc.pb.cc")
+%>\
+%endif
+%endfor
+%endif
+## remove all .proto includes
+<%
+ target.src = [item for item in target.src if not re.search('([^/]+)\.proto$', item)]
+%>\
%if target.name in build_from_project_file:
build_${target.name}:
msbuild grpc.sln /t:${target.name} /p:Configuration=Debug /p:Linkage-grpc_dependencies_zlib=static
@@ -116,11 +152,22 @@ build_${target.name}:
%if target.build == 'private':
Debug\${target.name}.lib: \
%else:
-${target.name}.exe: build_libs \
+${target.name}.exe: \
+%for dep in target.get('deps', []):
+%if dep in build_from_project_file:
+build_${dep} \
+%else:
+Debug\${dep}.lib \
+%endif
+%endfor
%endif
$(OUT_DIR)
echo Building ${target.name}
+%if target.language == 'c++':
+ $(CC) $(CXXFLAGS) /Fo:$(OUT_DIR)\ \
+%else:
$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ \
+%endif
%for source in target.src:
$(REPO_ROOT)\${to_windows_path(source)} \
%endfor
@@ -135,13 +182,19 @@ $(REPO_ROOT)\${to_windows_path('vsprojects/dummy.c')} \
%for dep in target.get('deps', []):
Debug\${dep}.lib \
%endfor
+%if target.language == 'c++':
+$(CXX_LIBS) \
+%endif
$(LIBS) \
%endif
-%for source in target.src:
-$(OUT_DIR)\${re.search('([^/]+)\.c$', source).group(1)}.obj \
-%endfor
%if not target.src:
$(OUT_DIR)\dummy.obj \
+%else:
+%for source in target.src:
+%if re.search('([^/]+)\.c{1,2}$', source):
+$(OUT_DIR)\${re.search('([^/]+)\.c{1,2}$', source).group(1)}.obj \
+%endif
+%endfor
%endif
%if target.build != 'private':
diff --git a/templates/vsprojects/build_test_protos.sh b/templates/vsprojects/build_test_protos.sh
new file mode 100644
index 0000000000..54edd3699a
--- /dev/null
+++ b/templates/vsprojects/build_test_protos.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# 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.
+
+GRPC_CPP_PLUGIN_PATH=`which grpc_cpp_plugin`
+
+cd `dirname $0`/../..
+
+find ./test -type f -name "*.proto" |
+while read p ; do
+ echo "processing $p"
+ DIR=$(dirname "$p")
+ protoc $p --grpc_out=./ --plugin=protoc-gen-grpc=$GRPC_CPP_PLUGIN_PATH
+ protoc $p --cpp_out=./
+done
diff --git a/templates/vsprojects/generate_debug_projects.sh b/templates/vsprojects/generate_debug_projects.sh
index 1bbe40b6c8..f103ebe01a 100755
--- a/templates/vsprojects/generate_debug_projects.sh
+++ b/templates/vsprojects/generate_debug_projects.sh
@@ -37,26 +37,40 @@
cd `dirname $0`/../..
-./tools/buildgen/generate_projects.sh
+git add . #because we're using "git diff" to find changes to grpc.sln and then make files based on those changes, this prevents this file or other files from possibly being found in the diff
-git diff |
-grep \\+Project |
-cut -d\" -f 4 |
-sort -u |
-grep _test$ |
-while read p ; do
- mkdir -p templates/vsprojects/$p
- echo '<%namespace file="../vcxproj_defs.include" import="gen_project"/>${gen_project("'$p'", targets)}' > templates/vsprojects/$p/$p.vcxproj.template
-done
+./tools/buildgen/generate_projects-old.sh
+
+line_number=0
git diff |
-grep \\+Project |
-cut -d\" -f 4 |
-sort -u |
-grep -v _test$ |
+grep -A2 \\+Project | #find "Project" immediately after a backslash (escaped), plus 2 additional lines to capture the "libs = ", plus 1 line of "--". matches will come from the generated grpc.sln
while read p ; do
- mkdir -p templates/vsprojects/$p
- echo '<%namespace file="../vcxproj_defs.include" import="gen_project"/>${gen_project("'$p'", libs)}' > templates/vsprojects/$p/$p.vcxproj.template
+ line_number=$((line_number + 1))
+ if [ "$line_number" -gt "4" ]; then
+ line_number=1;
+ fi
+ echo $line_number
+ echo $p
+ if [ "$line_number" -eq "1" ]; then
+ project_name=$(echo "$p" | cut -d\" -f 4) #sed: extract line N only; cut with delimiter: ". select only field 4
+ fi
+ if [ "$line_number" -eq "3" ]; then
+ lib_setting=$(echo "$p" | cut -d\" -f 2) #
+ echo "project_name"
+ echo $project_name
+ echo "lib_setting"
+ echo $lib_setting
+ mkdir -p templates/vsprojects/$project_name
+ if [ "$lib_setting" = "True" ]; then
+ echo "lib: true"
+ echo '<%namespace file="../vcxproj_defs.include" import="gen_project"/>${gen_project("'$project_name'", libs)}' > templates/vsprojects/$project_name/$project_name.vcxproj.template
+ else
+ echo "lib: not true"
+ echo '<%namespace file="../vcxproj_defs.include" import="gen_project"/>${gen_project("'$project_name'", targets)}' > templates/vsprojects/$project_name/$project_name.vcxproj.template
+ fi
+ fi
+ # sleep .5 #for testing
done
-./tools/buildgen/generate_projects.sh
+./tools/buildgen/generate_projects-old.sh
diff --git a/templates/vsprojects/sln_defs.include b/templates/vsprojects/sln_defs.include
index ee05d0fbde..4ba0fbff07 100644
--- a/templates/vsprojects/sln_defs.include
+++ b/templates/vsprojects/sln_defs.include
@@ -15,6 +15,13 @@ cpp_proj_type = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
%>\
% for project in solution_projects:
Project("${cpp_proj_type}") = "${project.name}", "${project.name}\${project.name}.vcxproj", "${project.vs_project_guid}"
+ ProjectSection(myProperties) = preProject
+ % if project.is_library:
+ lib = "True"
+ % else:
+ lib = "False"
+ % endif
+ EndProjectSection
% if project.get('deps', None):
ProjectSection(ProjectDependencies) = postProject
% for dep in project.get('deps', []):
@@ -47,4 +54,4 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
-</%def>\ \ No newline at end of file
+</%def>\
diff --git a/templates/vsprojects/vcxproj_defs.include b/templates/vsprojects/vcxproj_defs.include
index 55ec37393f..39c7386062 100644
--- a/templates/vsprojects/vcxproj_defs.include
+++ b/templates/vsprojects/vcxproj_defs.include
@@ -12,19 +12,21 @@
if t.name == name:
target = t
if not configuration_type and target:
+ print target.name
if target.build == 'test' or target.build == 'tool':
configuration_type = 'Application'
if not configuration_type:
configuration_type = 'StaticLibrary'
if not project_guid:
project_guid = project.vs_project_guid
+ if target.build == 'test' and target.language == 'c++':
+ props.extend(['cpptest'])
if configuration_type == 'Application':
+ print target.build
if target.build == 'protoc':
props.extend(['protoc'])
else:
props.extend(['winsock', 'protobuf', 'zlib', 'openssl'])
- if target.language == 'c++':
- props.extend(['protobuf'])
props.extend(['global'])
%>\
<?xml version="1.0" encoding="utf-8"?>
@@ -113,6 +115,13 @@ ${gen_package_props(packages)}\
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<TargetName>${name}</TargetName>
+ % if "zlib" in packages:
+ <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+ <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+ % endif
+ % if "openssl" in packages:
+ <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+ % endif
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<TargetName>${name}</TargetName>
@@ -200,8 +209,20 @@ ${gen_package_props(packages)}\
% if project.get('src',[]):
<ItemGroup>
% for src_name in project.src:
+ % if src_name.endswith(".proto"):
+<% src_name_parts = src_name.split(".") %>\
+ <ClCompile Include="${get_repo_root()}\${to_windows_path(src_name_parts[0] + ".pb.cc")}">
+ </ClCompile>
+ <ClInclude Include="${get_repo_root()}\${to_windows_path(src_name_parts[0] + ".pb.h")}">
+ </ClInclude>
+ <ClCompile Include="${get_repo_root()}\${to_windows_path(src_name_parts[0] + ".grpc.pb.cc")}">
+ </ClCompile>
+ <ClInclude Include="${get_repo_root()}\${to_windows_path(src_name_parts[0] + ".grpc.pb.h")}">
+ </ClInclude>
+ % else:
<ClCompile Include="${get_repo_root()}\${to_windows_path(src_name)}">
</ClCompile>
+ % endif
% endfor
</ItemGroup>
% elif configuration_type != 'StaticLibrary':
@@ -230,4 +251,4 @@ ${gen_package_targets(packages)}\
</ImportGroup>
${gen_package_ensure(packages)}\
</Project>
-</%def>\ \ No newline at end of file
+</%def>\
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 453376caec..77bea2abab 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -113,7 +113,7 @@ void test_connect(const char *server_host, const char *client_host, int port,
} else {
gpr_join_host_port(&client_hostport, client_host, port);
}
- client = grpc_channel_create(client_hostport, NULL);
+ client = grpc_insecure_channel_create(client_hostport, NULL);
gpr_log(GPR_INFO, "Testing with server=%s client=%s (expecting %s)",
server_hostport, client_hostport, expect_ok ? "success" : "failure");
diff --git a/test/core/end2end/fixtures/chttp2_fullstack.c b/test/core/end2end/fixtures/chttp2_fullstack.c
index 8a1530e63b..6647b949ba 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack.c
@@ -72,7 +72,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
fullstack_fixture_data *ffd = f->fixture_data;
- f->client = grpc_channel_create(ffd->localaddr, client_args);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args);
GPR_ASSERT(f->client);
}
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_compression.c b/test/core/end2end/fixtures/chttp2_fullstack_compression.c
index 0a9a312296..f3d1fa22dc 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_compression.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_compression.c
@@ -82,7 +82,8 @@ void chttp2_init_client_fullstack_compression(grpc_end2end_test_fixture *f,
}
ffd->client_args_compression = grpc_channel_args_set_compression_algorithm(
client_args, GRPC_COMPRESS_GZIP);
- f->client = grpc_channel_create(ffd->localaddr, ffd->client_args_compression);
+ f->client = grpc_insecure_channel_create(ffd->localaddr,
+ ffd->client_args_compression);
}
void chttp2_init_server_fullstack_compression(grpc_end2end_test_fixture *f,
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
index 351e1c5459..89ad7b8c2d 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix.c
@@ -78,7 +78,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
fullstack_fixture_data *ffd = f->fixture_data;
- f->client = grpc_channel_create(ffd->localaddr, client_args);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args);
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c
index 03d3be5a7c..a2ab25d886 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_uds_posix_with_poll.c
@@ -78,7 +78,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
fullstack_fixture_data *ffd = f->fixture_data;
- f->client = grpc_channel_create(ffd->localaddr, client_args);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args);
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
diff --git a/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c
index 69860d04d5..93786d0943 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c
@@ -72,7 +72,7 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
grpc_channel_args *client_args) {
fullstack_fixture_data *ffd = f->fixture_data;
- f->client = grpc_channel_create(ffd->localaddr, client_args);
+ f->client = grpc_insecure_channel_create(ffd->localaddr, client_args);
}
void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index 73a36116fb..6d5669d05a 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -115,7 +115,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
- grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1);
+ grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
}
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
index b1ac3e535f..d0cc3dd74a 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c
@@ -115,7 +115,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
- grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1);
+ grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0);
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
}
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index de418bf7ee..f74ed9365f 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -120,7 +120,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack(
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
- grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
+ grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0);
chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
}
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index 79797f9375..6f1133c009 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -61,7 +61,7 @@ int main(int argc, char **argv) {
cqv = cq_verifier_create(cq);
/* create a call, channel to a non existant server */
- chan = grpc_channel_create("nonexistant:54321", NULL);
+ chan = grpc_insecure_channel_create("nonexistant:54321", NULL);
call = grpc_channel_create_call(chan, cq, "/Foo", "nonexistant", deadline);
op = ops;
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
index ef6dfe9561..9821d7852f 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
@@ -111,8 +111,8 @@ static void test_request_response_with_metadata_and_payload(
gpr_timespec deadline = five_seconds_time();
grpc_metadata meta_c[2] = {{"key1", "val1", 4, {{NULL, NULL, NULL}}},
{"key2", "val2", 4, {{NULL, NULL, NULL}}}};
- grpc_metadata meta_s[2] = {{"key3", "val3", 4, {{NULL, NULL, NULL}}},
- {"key4", "val4", 4, {{NULL, NULL, NULL}}}};
+ grpc_metadata meta_s[2] = {{"KeY3", "val3", 4, {{NULL, NULL, NULL}}},
+ {"KeY4", "val4", 4, {{NULL, NULL, NULL}}}};
grpc_end2end_test_fixture f = begin_test(
config, "test_request_response_with_metadata_and_payload", NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq);
diff --git a/test/core/fling/client.c b/test/core/fling/client.c
index 2b19654379..5647a16101 100644
--- a/test/core/fling/client.c
+++ b/test/core/fling/client.c
@@ -183,7 +183,7 @@ int main(int argc, char **argv) {
return 1;
}
- channel = grpc_channel_create(target, NULL);
+ channel = grpc_insecure_channel_create(target, NULL);
cq = grpc_completion_queue_create();
the_buffer = grpc_raw_byte_buffer_create(&slice, payload_size);
histogram = gpr_histogram_create(0.01, 60e9);
diff --git a/test/core/fling/server.c b/test/core/fling/server.c
index 082bbd368a..8f349044d9 100644
--- a/test/core/fling/server.c
+++ b/test/core/fling/server.c
@@ -210,7 +210,7 @@ int main(int argc, char **argv) {
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials *ssl_creds =
- grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1);
+ grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1, 0);
server = grpc_server_create(NULL);
GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds));
grpc_server_credentials_release(ssl_creds);
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/core/transport/metadata_test.c b/test/core/transport/metadata_test.c
index a932e04f33..4a4d4bcb8a 100644
--- a/test/core/transport/metadata_test.c
+++ b/test/core/transport/metadata_test.c
@@ -63,9 +63,9 @@ static void test_create_string(void) {
LOG_TEST("test_create_string");
ctx = grpc_mdctx_create();
- s1 = grpc_mdstr_from_string(ctx, "hello");
- s2 = grpc_mdstr_from_string(ctx, "hello");
- s3 = grpc_mdstr_from_string(ctx, "very much not hello");
+ s1 = grpc_mdstr_from_string(ctx, "hello", 0);
+ s2 = grpc_mdstr_from_string(ctx, "hello", 0);
+ s3 = grpc_mdstr_from_string(ctx, "very much not hello", 0);
GPR_ASSERT(s1 == s2);
GPR_ASSERT(s3 != s1);
GPR_ASSERT(gpr_slice_str_cmp(s1->slice, "hello") == 0);
@@ -190,7 +190,7 @@ static void test_things_stick_around(void) {
for (i = 0; i < nstrs; i++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", i);
- strs[i] = grpc_mdstr_from_string(ctx, buffer);
+ strs[i] = grpc_mdstr_from_string(ctx, buffer, 0);
shuf[i] = i;
gpr_free(buffer);
}
@@ -212,7 +212,7 @@ static void test_things_stick_around(void) {
GRPC_MDSTR_UNREF(strs[shuf[i]]);
for (j = i + 1; j < nstrs; j++) {
gpr_asprintf(&buffer, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%dx", shuf[j]);
- test = grpc_mdstr_from_string(ctx, buffer);
+ test = grpc_mdstr_from_string(ctx, buffer, 0);
GPR_ASSERT(test == strs[shuf[j]]);
GRPC_MDSTR_UNREF(test);
gpr_free(buffer);
@@ -235,13 +235,13 @@ static void test_slices_work(void) {
ctx = grpc_mdctx_create();
str = grpc_mdstr_from_string(
- ctx, "123456789012345678901234567890123456789012345678901234567890");
+ ctx, "123456789012345678901234567890123456789012345678901234567890", 0);
slice = gpr_slice_ref(str->slice);
GRPC_MDSTR_UNREF(str);
gpr_slice_unref(slice);
str = grpc_mdstr_from_string(
- ctx, "123456789012345678901234567890123456789012345678901234567890");
+ ctx, "123456789012345678901234567890123456789012345678901234567890", 0);
slice = gpr_slice_ref(str->slice);
gpr_slice_unref(slice);
GRPC_MDSTR_UNREF(str);
@@ -258,7 +258,7 @@ static void test_base64_and_huffman_works(void) {
LOG_TEST("test_base64_and_huffman_works");
ctx = grpc_mdctx_create();
- str = grpc_mdstr_from_string(ctx, "abcdefg");
+ str = grpc_mdstr_from_string(ctx, "abcdefg", 0);
slice1 = grpc_mdstr_as_base64_encoded_and_huffman_compressed(str);
slice2 = grpc_chttp2_base64_encode_and_huffman_compress(str->slice);
GPR_ASSERT(0 == gpr_slice_cmp(slice1, slice2));
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/buildgen/generate_projects-old.sh b/tools/buildgen/generate_projects-old.sh
new file mode 100644
index 0000000000..5399867746
--- /dev/null
+++ b/tools/buildgen/generate_projects-old.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+# 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.
+
+
+set -e
+
+if [ "x$TEST" = "x" ] ; then
+ TEST=false
+fi
+
+
+cd `dirname $0`/../..
+mako_renderer=tools/buildgen/mako_renderer.py
+
+if [ "x$TEST" != "x" ] ; then
+ tools/buildgen/build-cleaner.py build.json
+fi
+
+. tools/buildgen/generate_build_additions.sh
+
+global_plugins=`find ./tools/buildgen/plugins -name '*.py' |
+ sort | grep -v __init__ | awk ' { printf "-p %s ", $0 } '`
+
+for dir in . ; do
+ local_plugins=`find $dir/templates -name '*.py' |
+ sort | grep -v __init__ | awk ' { printf "-p %s ", $0 } '`
+
+ plugins="$global_plugins $local_plugins"
+
+ find -L $dir/templates -type f -and -name *.template | while read file ; do
+ out=${dir}/${file#$dir/templates/} # strip templates dir prefix
+ out=${out%.*} # strip template extension
+ echo "generating file: $out"
+ json_files="build.json $gen_build_files"
+ data=`for i in $json_files ; do echo $i ; done | awk ' { printf "-d %s ", $0 } '`
+ if [ "x$TEST" = "xtrue" ] ; then
+ actual_out=$out
+ out=`mktemp /tmp/gentXXXXXX`
+ fi
+ mkdir -p `dirname $out` # make sure dest directory exist
+ $mako_renderer $plugins $data -o $out $file
+ if [ "x$TEST" = "xtrue" ] ; then
+ diff -q $out $actual_out
+ rm $out
+ fi
+ done
+done
+
+rm $gen_build_files
diff --git a/tools/buildgen/plugins/generate_vsprojects.py b/tools/buildgen/plugins/generate_vsprojects.py
index 150e72e0b2..413056fe89 100755
--- a/tools/buildgen/plugins/generate_vsprojects.py
+++ b/tools/buildgen/plugins/generate_vsprojects.py
@@ -70,7 +70,7 @@ def mako_plugin(dictionary):
if project.get('vs_project_guid', None)]
projects = [project for project in projects
- if project['language'] != 'c++' or project['build'] == 'all' or project['build'] == 'protoc']
+ if project['language'] != 'c++' or project['build'] == 'all' or project['build'] == 'protoc' or (project['language'] == 'c++' and (project['build'] == 'test' or project['build'] == 'private'))]
project_dict = dict([(p['name'], p) for p in projects])
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/README.md b/vsprojects/README.md
index dade9e500e..e6cbf83359 100644
--- a/vsprojects/README.md
+++ b/vsprojects/README.md
@@ -19,19 +19,62 @@ After that, you can build the solution using one of these options:
1. open `grpc.sln` with Visual Studio and hit "Build".
2. build from commandline using `msbuild grpc.sln /p:Configuration=Debug`
-#Testing
+#C/C++ Test Dependencies
+ * gtest isn't available as a git repo like the other dependencies. download it and add it to `/third_party/gtest/` (the folder will end up with `/build-aux/`, `/cmake/`, `/codegear/`, etc. folders in it).
+ * if using vs2013: open/import the gtest solution in `/msvc/`, and save over the first solution (you will have to change it from read-only). change all projects to use `/MDd` (Property Pages - C/C++ - Code Generation - Runtime Library) and build. This is a "multithreaded debug" setting and it needs to match grpc.
+ * build all
+ * open protobuf solution in `/third_party/protobuf/vsprojects`
+ * if using vs2013: on import the gtest stuff will probably fail, I think the paths are interpreted wrong. it's ok.
+ * tests and test_plugin will fail when built. also ok
+ * build all
+ * gflags is automatically imported as a git submodule but it needs to have CMake run on it to be ready for a specific platform
+ * download [CMake](http://www.cmake.org/) windows installer; install
+ * open visual studio developer command prompt (not sure if dev command prompt is necessary)
+ * run `cmake <path to gtest directory>`
+ * this will build a `.sln` and fill up the `/third_party/gflags/include/gflags/` directory with headers
+ * build all
+ * install [NuGet](http://www.nuget.org)
+ * nuget should automatically bring in built versions of zlib and openssl when building grpc.sln (the versions in `/third_party/` are not used). If it doesn't work use `tools->nuget...->manage...`. The packages are put in `/vsprojects/packages/`
-Use `run_tests.py`, that also supports Windows (with a bit limited experience).
-```
-> REM Run from repository root.
-> python tools\run_tests\run_tests.py -l c
-```
+#C/C++ Test Solution/Project Build Steps
+ * A basic git version of grpc only has templates for non-test items. This checklist adds test items to grpc.sln and makes individual vs projects for them
+ * set up dependencies (above)
+ * add `"debug": true,` to the top of build.json. This is the base file for all build tracking, see [templates](https://github.com/grpc/grpc/tree/master/templates) for more information
+ * `"debug": true,` gets picked up by `/tools/buildgen/plugins/generate_vsprojects.py`. It tells the script to add visual studio GUIDs to all projects. Otherwise only the projects that already have GUIDs in build.json will be built
+ * run `/templates/vsprojects/generate_debug_projects.sh` to make debug templates/projects. This runs a regular visual studio buildgen process, which creates the `.sln` file with all of the new debug projects, then uses git diff to find the new project names from the `.sln` that need templates added. It builds the new templates based on the diff, then re-runs the visual studio buildgen, which builds the vs projects for each of the new debug targets
+ * copy over the `/vsprojects/` folder to your windows build setup (assuming this was built on linux in order to have easy access to python/mako and shell scripts)
+ * run `/templates/vsprojects/build_test_protos.sh`
+ * this builds all `.proto` files in `/test/` in-place. there might be a better place to put them that mirrors what happens in the linux build process (todo)
+ * each `.proto` file gets built into a `.grpc.pb.cc`, .`grpc.pb.h`, `.pb.cc`, and `.pb.h`. These are included in each test project in lieu of the `.proto` includes specified in `build.json`. This substitution is done by `/templates/vsprojects/vcxproj_defs.include`
+ * copy over the `/test/` folder in order to get the new files (assuming this was built on linux in order to have an easy protobuf+grpc plugin installation)
-Also, you can `make.bat` directly to build and run gRPC tests.
-```
-> REM Run from this directory.
-> make.bat alarm_test
-```
+#Making and running tests with `/tools/run_tests/run_tests.py` or `/vsprojects/make.bat`
+`run_tests.py` and `make.bat` both rely on `/vsprojects/grpc.mak`, an NMAKE script that includes C/C++ tests in addition to the base grpc projects. It builds the base projects by calling grpc.sln, but most things are built with a command line similar to a makefile workflow.
+
+ arguments for `/vsprojects/make.bat`:
+
+ * no options or `all` or `buildtests`: builds all tests
+ * `buildtests_c`: just c tests
+ * `buildtests_cxx`: just c++ tests
+ * names of individual tests: just those tests (example: `make.bat gpr_string_test`)
+
+using `run_tests.py` on windows:
+
+ * when `run_tests.py` detects that it's running on windows it calls `make.bat` to build the tests and expects to find tests in `/vsprojects/test_bins/`
+
+`run_tests.py` options:
+
+ * `run_tests.py --help`
+ * `run_tests.py -l c`: run c language tests
+ * `run_tests.py -l c++`: run c++ language tests
+ * note: `run_tests.py` doesn't normally show build steps, so if a build fails it is best to fall back to `make.bat`
+ * if `make.bat` fails, it might be easier to open up the `.sln` file in the visual studio gui (see above for how to build the test projects) and build the offending test from its project file. The `.mak` and project file templates are slightly different, so it's possible that a project will build one way and not another. Please report this if it happens.
+
+It can be helpful to disable the firewall when running tests so that 400 connection warnings don't pop up.
+
+Individual tests can be run by directly running the executable in `/vsprojects/run_tests/` (this is `/bins/opt/` on linux). Many C tests have no output; they either pass or fail internally and communicate this with their exit code (`0=pass`, `nonzero=fail`)
+
+`run_tests.py` will fail if it can't build something, so not-building tests are disabled with a "platforms = posix" note in build.json. The buildgen tools will not add a test to a windows build unless it is marked "windows" or has no platforms identified. As tests are ported they will get this mark removed.
# Building protoc plugins
For generating service stub code, gRPC relies on plugins for `protoc` (the protocol buffer compiler). The solution `grpc_protoc_plugins.sln` allows you to build
diff --git a/vsprojects/cpptest.props b/vsprojects/cpptest.props
new file mode 100644
index 0000000000..c5ffd54f99
--- /dev/null
+++ b/vsprojects/cpptest.props
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(ProjectDir)\..\..;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\third_party\protobuf\src;$(ProjectDir)\..\..\third_party\gtest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>grpc++_test_util.lib;grpc_test_util.lib;gpr_test_util.lib;gtestd.lib;gflags.lib;shlwapi.lib;gpr.lib;grpc.lib;grpc++.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(ProjectDir)\..\..\third_party\gtest\msvc\gtest\Debug;$(ProjectDir)\..\..\third_party\gflags\lib\Debug;$(ProjectDir)\..\Debug;$(ProjectDir)\..\packages\grpc.dependencies.openssl.1.0.2.2\build\native\lib\$(PlatformToolset)\$(Platform)\$(Configuration)\static;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project>
diff --git a/vsprojects/global.props b/vsprojects/global.props
index 14acf4668b..6858bd7b9d 100644
--- a/vsprojects/global.props
+++ b/vsprojects/global.props
@@ -5,10 +5,10 @@
<PropertyGroup />
<ItemDefinitionGroup>
<ClCompile>
- <AdditionalIncludeDirectories>$(ProjectDir)\..\..;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\third_party\protobuf\src;$(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(ProjectDir)\..\..;$(ProjectDir)\..\..\include;$(ProjectDir)\..\..\third_party\protobuf\src;$(ProjectDir)\..\packages\grpc.dependencies.openssl.1.0.2.2\build\native\include;$(ProjectDir)\..\..\third_party\gflags\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_SCL_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>EnableAllWarnings</WarningLevel>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup />
-</Project> \ No newline at end of file
+</Project>
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>
diff --git a/vsprojects/make.bat b/vsprojects/make.bat
index 04737aeefc..08c97bcd21 100644
--- a/vsprojects/make.bat
+++ b/vsprojects/make.bat
@@ -5,6 +5,7 @@ setlocal
@rem Set VS variables (uses Visual Studio 2013)
@call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
-nmake /f Grpc.mak %*
+@rem /K: continue on error
+nmake /K /f Grpc.mak %*
exit /b %ERRORLEVEL%
-endlocal \ No newline at end of file
+endlocal