diff options
author | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2015-04-10 22:39:44 +0200 |
---|---|---|
committer | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2015-04-10 22:39:44 +0200 |
commit | 7a6d8fde095501016dc98f43299be2facc79f17e (patch) | |
tree | f88972d1f17e78920ee1228dee061878562dd27b | |
parent | f0863b02270f1b95d5c8b9f3f962959e4cbbdd42 (diff) | |
parent | 046c6656c961bb65508d725edb9adc60f63e3424 (diff) |
Merge branch 'master' of github.com:grpc/grpc into freebsd
301 files changed, 12075 insertions, 4662 deletions
diff --git a/.gitmodules b/.gitmodules index 97b7197be3..557321001f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,4 +11,4 @@ branch = v3.0.0-alpha-1 [submodule "third_party/gflags"] path = third_party/gflags - url = https://code.google.com/p/gflags + url = https://github.com/gflags/gflags.git diff --git a/.travis.yml b/.travis.yml index e43a89e453..165f8923c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,9 +19,12 @@ env: - CONFIG=opt TEST=python - CONFIG=gcov TEST=c - CONFIG=gcov TEST=c++ + - USE_GCC=4.4 CONFIG=opt TEST=build + - USE_GCC=4.5 CONFIG=opt TEST=build script: - rvm use $RUBY_VERSION - gem install bundler + - if [ ! -z "$USE_GCC" ] ; then export CC=gcc-$USE_GCC ; export CXX=g++-$USE_GCC ; fi - ./tools/run_tests/run_tests.py -l $TEST -t -j 16 -c $CONFIG -s 4.0 after_success: - if [ "$CONFIG" = "gcov" ] ; then coveralls --exclude third_party --exclude gens -b. --gcov-options '\-p' ; fi @@ -0,0 +1,813 @@ +# GRPC Bazel BUILD file. +# This currently builds C and C++ code. + +# 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. + +licenses(["notice"]) # 3-clause BSD + +package(default_visibility = ["//visibility:public"]) + + + + +cc_library( + name = "gpr", + srcs = [ + "src/core/support/env.h", + "src/core/support/file.h", + "src/core/support/murmur_hash.h", + "src/core/support/string.h", + "src/core/support/string_win32.h", + "src/core/support/thd_internal.h", + "src/core/support/alloc.c", + "src/core/support/cancellable.c", + "src/core/support/cmdline.c", + "src/core/support/cpu_iphone.c", + "src/core/support/cpu_linux.c", + "src/core/support/cpu_posix.c", + "src/core/support/cpu_windows.c", + "src/core/support/env_linux.c", + "src/core/support/env_posix.c", + "src/core/support/env_win32.c", + "src/core/support/file.c", + "src/core/support/file_posix.c", + "src/core/support/file_win32.c", + "src/core/support/histogram.c", + "src/core/support/host_port.c", + "src/core/support/log.c", + "src/core/support/log_android.c", + "src/core/support/log_linux.c", + "src/core/support/log_posix.c", + "src/core/support/log_win32.c", + "src/core/support/murmur_hash.c", + "src/core/support/slice.c", + "src/core/support/slice_buffer.c", + "src/core/support/string.c", + "src/core/support/string_posix.c", + "src/core/support/string_win32.c", + "src/core/support/sync.c", + "src/core/support/sync_posix.c", + "src/core/support/sync_win32.c", + "src/core/support/thd.c", + "src/core/support/thd_posix.c", + "src/core/support/thd_win32.c", + "src/core/support/time.c", + "src/core/support/time_posix.c", + "src/core/support/time_win32.c", + ], + hdrs = [ + "include/grpc/support/alloc.h", + "include/grpc/support/atm.h", + "include/grpc/support/atm_gcc_atomic.h", + "include/grpc/support/atm_gcc_sync.h", + "include/grpc/support/atm_win32.h", + "include/grpc/support/cancellable_platform.h", + "include/grpc/support/cmdline.h", + "include/grpc/support/cpu.h", + "include/grpc/support/histogram.h", + "include/grpc/support/host_port.h", + "include/grpc/support/log.h", + "include/grpc/support/log_win32.h", + "include/grpc/support/port_platform.h", + "include/grpc/support/slice.h", + "include/grpc/support/slice_buffer.h", + "include/grpc/support/sync.h", + "include/grpc/support/sync_generic.h", + "include/grpc/support/sync_posix.h", + "include/grpc/support/sync_win32.h", + "include/grpc/support/thd.h", + "include/grpc/support/time.h", + "include/grpc/support/useful.h", + ], + includes = [ + "include", + ".", + ], + deps = [ + ], +) + + +cc_library( + name = "grpc", + srcs = [ + "src/core/httpcli/format_request.h", + "src/core/httpcli/httpcli.h", + "src/core/httpcli/httpcli_security_context.h", + "src/core/httpcli/parser.h", + "src/core/security/auth.h", + "src/core/security/base64.h", + "src/core/security/credentials.h", + "src/core/security/json_token.h", + "src/core/security/secure_endpoint.h", + "src/core/security/secure_transport_setup.h", + "src/core/security/security_context.h", + "src/core/tsi/fake_transport_security.h", + "src/core/tsi/ssl_transport_security.h", + "src/core/tsi/transport_security.h", + "src/core/tsi/transport_security_interface.h", + "src/core/channel/census_filter.h", + "src/core/channel/channel_args.h", + "src/core/channel/channel_stack.h", + "src/core/channel/child_channel.h", + "src/core/channel/client_channel.h", + "src/core/channel/client_setup.h", + "src/core/channel/connected_channel.h", + "src/core/channel/http_client_filter.h", + "src/core/channel/http_filter.h", + "src/core/channel/http_server_filter.h", + "src/core/channel/metadata_buffer.h", + "src/core/channel/noop_filter.h", + "src/core/compression/algorithm.h", + "src/core/compression/message_compress.h", + "src/core/debug/trace.h", + "src/core/iomgr/alarm.h", + "src/core/iomgr/alarm_heap.h", + "src/core/iomgr/alarm_internal.h", + "src/core/iomgr/endpoint.h", + "src/core/iomgr/endpoint_pair.h", + "src/core/iomgr/fd_posix.h", + "src/core/iomgr/iocp_windows.h", + "src/core/iomgr/iomgr.h", + "src/core/iomgr/iomgr_internal.h", + "src/core/iomgr/iomgr_posix.h", + "src/core/iomgr/pollset.h", + "src/core/iomgr/pollset_kick.h", + "src/core/iomgr/pollset_kick_posix.h", + "src/core/iomgr/pollset_kick_windows.h", + "src/core/iomgr/pollset_posix.h", + "src/core/iomgr/pollset_windows.h", + "src/core/iomgr/resolve_address.h", + "src/core/iomgr/sockaddr.h", + "src/core/iomgr/sockaddr_posix.h", + "src/core/iomgr/sockaddr_utils.h", + "src/core/iomgr/sockaddr_win32.h", + "src/core/iomgr/socket_utils_posix.h", + "src/core/iomgr/socket_windows.h", + "src/core/iomgr/tcp_client.h", + "src/core/iomgr/tcp_posix.h", + "src/core/iomgr/tcp_server.h", + "src/core/iomgr/tcp_windows.h", + "src/core/iomgr/time_averaged_stats.h", + "src/core/iomgr/wakeup_fd_pipe.h", + "src/core/iomgr/wakeup_fd_posix.h", + "src/core/json/json.h", + "src/core/json/json_common.h", + "src/core/json/json_reader.h", + "src/core/json/json_writer.h", + "src/core/statistics/census_interface.h", + "src/core/statistics/census_log.h", + "src/core/statistics/census_rpc_stats.h", + "src/core/statistics/census_tracing.h", + "src/core/statistics/hash_table.h", + "src/core/statistics/window_stats.h", + "src/core/surface/byte_buffer_queue.h", + "src/core/surface/call.h", + "src/core/surface/channel.h", + "src/core/surface/client.h", + "src/core/surface/completion_queue.h", + "src/core/surface/event_string.h", + "src/core/surface/init.h", + "src/core/surface/server.h", + "src/core/surface/surface_trace.h", + "src/core/transport/chttp2/alpn.h", + "src/core/transport/chttp2/bin_encoder.h", + "src/core/transport/chttp2/frame.h", + "src/core/transport/chttp2/frame_data.h", + "src/core/transport/chttp2/frame_goaway.h", + "src/core/transport/chttp2/frame_ping.h", + "src/core/transport/chttp2/frame_rst_stream.h", + "src/core/transport/chttp2/frame_settings.h", + "src/core/transport/chttp2/frame_window_update.h", + "src/core/transport/chttp2/hpack_parser.h", + "src/core/transport/chttp2/hpack_table.h", + "src/core/transport/chttp2/http2_errors.h", + "src/core/transport/chttp2/huffsyms.h", + "src/core/transport/chttp2/status_conversion.h", + "src/core/transport/chttp2/stream_encoder.h", + "src/core/transport/chttp2/stream_map.h", + "src/core/transport/chttp2/timeout_encoding.h", + "src/core/transport/chttp2/varint.h", + "src/core/transport/chttp2_transport.h", + "src/core/transport/metadata.h", + "src/core/transport/stream_op.h", + "src/core/transport/transport.h", + "src/core/transport/transport_impl.h", + "src/core/httpcli/format_request.c", + "src/core/httpcli/httpcli.c", + "src/core/httpcli/httpcli_security_context.c", + "src/core/httpcli/parser.c", + "src/core/security/auth.c", + "src/core/security/base64.c", + "src/core/security/credentials.c", + "src/core/security/credentials_posix.c", + "src/core/security/credentials_win32.c", + "src/core/security/factories.c", + "src/core/security/google_default_credentials.c", + "src/core/security/json_token.c", + "src/core/security/secure_endpoint.c", + "src/core/security/secure_transport_setup.c", + "src/core/security/security_context.c", + "src/core/security/server_secure_chttp2.c", + "src/core/surface/init_secure.c", + "src/core/surface/secure_channel_create.c", + "src/core/tsi/fake_transport_security.c", + "src/core/tsi/ssl_transport_security.c", + "src/core/tsi/transport_security.c", + "src/core/channel/call_op_string.c", + "src/core/channel/census_filter.c", + "src/core/channel/channel_args.c", + "src/core/channel/channel_stack.c", + "src/core/channel/child_channel.c", + "src/core/channel/client_channel.c", + "src/core/channel/client_setup.c", + "src/core/channel/connected_channel.c", + "src/core/channel/http_client_filter.c", + "src/core/channel/http_filter.c", + "src/core/channel/http_server_filter.c", + "src/core/channel/metadata_buffer.c", + "src/core/channel/noop_filter.c", + "src/core/compression/algorithm.c", + "src/core/compression/message_compress.c", + "src/core/debug/trace.c", + "src/core/iomgr/alarm.c", + "src/core/iomgr/alarm_heap.c", + "src/core/iomgr/endpoint.c", + "src/core/iomgr/endpoint_pair_posix.c", + "src/core/iomgr/fd_posix.c", + "src/core/iomgr/iocp_windows.c", + "src/core/iomgr/iomgr.c", + "src/core/iomgr/iomgr_posix.c", + "src/core/iomgr/iomgr_windows.c", + "src/core/iomgr/pollset_kick.c", + "src/core/iomgr/pollset_multipoller_with_epoll.c", + "src/core/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/iomgr/pollset_posix.c", + "src/core/iomgr/pollset_windows.c", + "src/core/iomgr/resolve_address_posix.c", + "src/core/iomgr/resolve_address_windows.c", + "src/core/iomgr/sockaddr_utils.c", + "src/core/iomgr/socket_utils_common_posix.c", + "src/core/iomgr/socket_utils_linux.c", + "src/core/iomgr/socket_utils_posix.c", + "src/core/iomgr/socket_windows.c", + "src/core/iomgr/tcp_client_posix.c", + "src/core/iomgr/tcp_client_windows.c", + "src/core/iomgr/tcp_posix.c", + "src/core/iomgr/tcp_server_posix.c", + "src/core/iomgr/tcp_server_windows.c", + "src/core/iomgr/tcp_windows.c", + "src/core/iomgr/time_averaged_stats.c", + "src/core/iomgr/wakeup_fd_eventfd.c", + "src/core/iomgr/wakeup_fd_nospecial.c", + "src/core/iomgr/wakeup_fd_pipe.c", + "src/core/iomgr/wakeup_fd_posix.c", + "src/core/json/json.c", + "src/core/json/json_reader.c", + "src/core/json/json_string.c", + "src/core/json/json_writer.c", + "src/core/statistics/census_init.c", + "src/core/statistics/census_log.c", + "src/core/statistics/census_rpc_stats.c", + "src/core/statistics/census_tracing.c", + "src/core/statistics/hash_table.c", + "src/core/statistics/window_stats.c", + "src/core/surface/byte_buffer.c", + "src/core/surface/byte_buffer_queue.c", + "src/core/surface/byte_buffer_reader.c", + "src/core/surface/call.c", + "src/core/surface/call_details.c", + "src/core/surface/call_log_batch.c", + "src/core/surface/channel.c", + "src/core/surface/channel_create.c", + "src/core/surface/client.c", + "src/core/surface/completion_queue.c", + "src/core/surface/event_string.c", + "src/core/surface/init.c", + "src/core/surface/lame_client.c", + "src/core/surface/metadata_array.c", + "src/core/surface/server.c", + "src/core/surface/server_chttp2.c", + "src/core/surface/server_create.c", + "src/core/surface/surface_trace.c", + "src/core/transport/chttp2/alpn.c", + "src/core/transport/chttp2/bin_encoder.c", + "src/core/transport/chttp2/frame_data.c", + "src/core/transport/chttp2/frame_goaway.c", + "src/core/transport/chttp2/frame_ping.c", + "src/core/transport/chttp2/frame_rst_stream.c", + "src/core/transport/chttp2/frame_settings.c", + "src/core/transport/chttp2/frame_window_update.c", + "src/core/transport/chttp2/hpack_parser.c", + "src/core/transport/chttp2/hpack_table.c", + "src/core/transport/chttp2/huffsyms.c", + "src/core/transport/chttp2/status_conversion.c", + "src/core/transport/chttp2/stream_encoder.c", + "src/core/transport/chttp2/stream_map.c", + "src/core/transport/chttp2/timeout_encoding.c", + "src/core/transport/chttp2/varint.c", + "src/core/transport/chttp2_transport.c", + "src/core/transport/metadata.c", + "src/core/transport/stream_op.c", + "src/core/transport/transport.c", + ], + hdrs = [ + "include/grpc/grpc_security.h", + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/grpc.h", + "include/grpc/grpc_http.h", + "include/grpc/status.h", + ], + includes = [ + "include", + ".", + ], + deps = [ + "//external:libssl", + ":gpr", + ], +) + + +cc_library( + name = "grpc_unsecure", + srcs = [ + "src/core/channel/census_filter.h", + "src/core/channel/channel_args.h", + "src/core/channel/channel_stack.h", + "src/core/channel/child_channel.h", + "src/core/channel/client_channel.h", + "src/core/channel/client_setup.h", + "src/core/channel/connected_channel.h", + "src/core/channel/http_client_filter.h", + "src/core/channel/http_filter.h", + "src/core/channel/http_server_filter.h", + "src/core/channel/metadata_buffer.h", + "src/core/channel/noop_filter.h", + "src/core/compression/algorithm.h", + "src/core/compression/message_compress.h", + "src/core/debug/trace.h", + "src/core/iomgr/alarm.h", + "src/core/iomgr/alarm_heap.h", + "src/core/iomgr/alarm_internal.h", + "src/core/iomgr/endpoint.h", + "src/core/iomgr/endpoint_pair.h", + "src/core/iomgr/fd_posix.h", + "src/core/iomgr/iocp_windows.h", + "src/core/iomgr/iomgr.h", + "src/core/iomgr/iomgr_internal.h", + "src/core/iomgr/iomgr_posix.h", + "src/core/iomgr/pollset.h", + "src/core/iomgr/pollset_kick.h", + "src/core/iomgr/pollset_kick_posix.h", + "src/core/iomgr/pollset_kick_windows.h", + "src/core/iomgr/pollset_posix.h", + "src/core/iomgr/pollset_windows.h", + "src/core/iomgr/resolve_address.h", + "src/core/iomgr/sockaddr.h", + "src/core/iomgr/sockaddr_posix.h", + "src/core/iomgr/sockaddr_utils.h", + "src/core/iomgr/sockaddr_win32.h", + "src/core/iomgr/socket_utils_posix.h", + "src/core/iomgr/socket_windows.h", + "src/core/iomgr/tcp_client.h", + "src/core/iomgr/tcp_posix.h", + "src/core/iomgr/tcp_server.h", + "src/core/iomgr/tcp_windows.h", + "src/core/iomgr/time_averaged_stats.h", + "src/core/iomgr/wakeup_fd_pipe.h", + "src/core/iomgr/wakeup_fd_posix.h", + "src/core/json/json.h", + "src/core/json/json_common.h", + "src/core/json/json_reader.h", + "src/core/json/json_writer.h", + "src/core/statistics/census_interface.h", + "src/core/statistics/census_log.h", + "src/core/statistics/census_rpc_stats.h", + "src/core/statistics/census_tracing.h", + "src/core/statistics/hash_table.h", + "src/core/statistics/window_stats.h", + "src/core/surface/byte_buffer_queue.h", + "src/core/surface/call.h", + "src/core/surface/channel.h", + "src/core/surface/client.h", + "src/core/surface/completion_queue.h", + "src/core/surface/event_string.h", + "src/core/surface/init.h", + "src/core/surface/server.h", + "src/core/surface/surface_trace.h", + "src/core/transport/chttp2/alpn.h", + "src/core/transport/chttp2/bin_encoder.h", + "src/core/transport/chttp2/frame.h", + "src/core/transport/chttp2/frame_data.h", + "src/core/transport/chttp2/frame_goaway.h", + "src/core/transport/chttp2/frame_ping.h", + "src/core/transport/chttp2/frame_rst_stream.h", + "src/core/transport/chttp2/frame_settings.h", + "src/core/transport/chttp2/frame_window_update.h", + "src/core/transport/chttp2/hpack_parser.h", + "src/core/transport/chttp2/hpack_table.h", + "src/core/transport/chttp2/http2_errors.h", + "src/core/transport/chttp2/huffsyms.h", + "src/core/transport/chttp2/status_conversion.h", + "src/core/transport/chttp2/stream_encoder.h", + "src/core/transport/chttp2/stream_map.h", + "src/core/transport/chttp2/timeout_encoding.h", + "src/core/transport/chttp2/varint.h", + "src/core/transport/chttp2_transport.h", + "src/core/transport/metadata.h", + "src/core/transport/stream_op.h", + "src/core/transport/transport.h", + "src/core/transport/transport_impl.h", + "src/core/surface/init_unsecure.c", + "src/core/channel/call_op_string.c", + "src/core/channel/census_filter.c", + "src/core/channel/channel_args.c", + "src/core/channel/channel_stack.c", + "src/core/channel/child_channel.c", + "src/core/channel/client_channel.c", + "src/core/channel/client_setup.c", + "src/core/channel/connected_channel.c", + "src/core/channel/http_client_filter.c", + "src/core/channel/http_filter.c", + "src/core/channel/http_server_filter.c", + "src/core/channel/metadata_buffer.c", + "src/core/channel/noop_filter.c", + "src/core/compression/algorithm.c", + "src/core/compression/message_compress.c", + "src/core/debug/trace.c", + "src/core/iomgr/alarm.c", + "src/core/iomgr/alarm_heap.c", + "src/core/iomgr/endpoint.c", + "src/core/iomgr/endpoint_pair_posix.c", + "src/core/iomgr/fd_posix.c", + "src/core/iomgr/iocp_windows.c", + "src/core/iomgr/iomgr.c", + "src/core/iomgr/iomgr_posix.c", + "src/core/iomgr/iomgr_windows.c", + "src/core/iomgr/pollset_kick.c", + "src/core/iomgr/pollset_multipoller_with_epoll.c", + "src/core/iomgr/pollset_multipoller_with_poll_posix.c", + "src/core/iomgr/pollset_posix.c", + "src/core/iomgr/pollset_windows.c", + "src/core/iomgr/resolve_address_posix.c", + "src/core/iomgr/resolve_address_windows.c", + "src/core/iomgr/sockaddr_utils.c", + "src/core/iomgr/socket_utils_common_posix.c", + "src/core/iomgr/socket_utils_linux.c", + "src/core/iomgr/socket_utils_posix.c", + "src/core/iomgr/socket_windows.c", + "src/core/iomgr/tcp_client_posix.c", + "src/core/iomgr/tcp_client_windows.c", + "src/core/iomgr/tcp_posix.c", + "src/core/iomgr/tcp_server_posix.c", + "src/core/iomgr/tcp_server_windows.c", + "src/core/iomgr/tcp_windows.c", + "src/core/iomgr/time_averaged_stats.c", + "src/core/iomgr/wakeup_fd_eventfd.c", + "src/core/iomgr/wakeup_fd_nospecial.c", + "src/core/iomgr/wakeup_fd_pipe.c", + "src/core/iomgr/wakeup_fd_posix.c", + "src/core/json/json.c", + "src/core/json/json_reader.c", + "src/core/json/json_string.c", + "src/core/json/json_writer.c", + "src/core/statistics/census_init.c", + "src/core/statistics/census_log.c", + "src/core/statistics/census_rpc_stats.c", + "src/core/statistics/census_tracing.c", + "src/core/statistics/hash_table.c", + "src/core/statistics/window_stats.c", + "src/core/surface/byte_buffer.c", + "src/core/surface/byte_buffer_queue.c", + "src/core/surface/byte_buffer_reader.c", + "src/core/surface/call.c", + "src/core/surface/call_details.c", + "src/core/surface/call_log_batch.c", + "src/core/surface/channel.c", + "src/core/surface/channel_create.c", + "src/core/surface/client.c", + "src/core/surface/completion_queue.c", + "src/core/surface/event_string.c", + "src/core/surface/init.c", + "src/core/surface/lame_client.c", + "src/core/surface/metadata_array.c", + "src/core/surface/server.c", + "src/core/surface/server_chttp2.c", + "src/core/surface/server_create.c", + "src/core/surface/surface_trace.c", + "src/core/transport/chttp2/alpn.c", + "src/core/transport/chttp2/bin_encoder.c", + "src/core/transport/chttp2/frame_data.c", + "src/core/transport/chttp2/frame_goaway.c", + "src/core/transport/chttp2/frame_ping.c", + "src/core/transport/chttp2/frame_rst_stream.c", + "src/core/transport/chttp2/frame_settings.c", + "src/core/transport/chttp2/frame_window_update.c", + "src/core/transport/chttp2/hpack_parser.c", + "src/core/transport/chttp2/hpack_table.c", + "src/core/transport/chttp2/huffsyms.c", + "src/core/transport/chttp2/status_conversion.c", + "src/core/transport/chttp2/stream_encoder.c", + "src/core/transport/chttp2/stream_map.c", + "src/core/transport/chttp2/timeout_encoding.c", + "src/core/transport/chttp2/varint.c", + "src/core/transport/chttp2_transport.c", + "src/core/transport/metadata.c", + "src/core/transport/stream_op.c", + "src/core/transport/transport.c", + ], + hdrs = [ + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/grpc.h", + "include/grpc/grpc_http.h", + "include/grpc/status.h", + ], + includes = [ + "include", + ".", + ], + deps = [ + ":gpr", + ], +) + + +cc_library( + name = "grpc++", + srcs = [ + "src/cpp/client/secure_credentials.h", + "src/cpp/server/secure_server_credentials.h", + "src/cpp/client/channel.h", + "src/cpp/proto/proto_utils.h", + "src/cpp/server/thread_pool.h", + "src/cpp/util/time.h", + "src/cpp/client/secure_credentials.cc", + "src/cpp/server/secure_server_credentials.cc", + "src/cpp/client/channel.cc", + "src/cpp/client/channel_arguments.cc", + "src/cpp/client/client_context.cc", + "src/cpp/client/client_unary_call.cc", + "src/cpp/client/create_channel.cc", + "src/cpp/client/credentials.cc", + "src/cpp/client/generic_stub.cc", + "src/cpp/client/insecure_credentials.cc", + "src/cpp/client/internal_stub.cc", + "src/cpp/common/call.cc", + "src/cpp/common/completion_queue.cc", + "src/cpp/common/rpc_method.cc", + "src/cpp/proto/proto_utils.cc", + "src/cpp/server/async_generic_service.cc", + "src/cpp/server/insecure_server_credentials.cc", + "src/cpp/server/server.cc", + "src/cpp/server/server_builder.cc", + "src/cpp/server/server_context.cc", + "src/cpp/server/server_credentials.cc", + "src/cpp/server/thread_pool.cc", + "src/cpp/util/byte_buffer.cc", + "src/cpp/util/slice.cc", + "src/cpp/util/status.cc", + "src/cpp/util/time.cc", + ], + hdrs = [ + "include/grpc++/async_generic_service.h", + "include/grpc++/async_unary_call.h", + "include/grpc++/byte_buffer.h", + "include/grpc++/channel_arguments.h", + "include/grpc++/channel_interface.h", + "include/grpc++/client_context.h", + "include/grpc++/completion_queue.h", + "include/grpc++/config.h", + "include/grpc++/create_channel.h", + "include/grpc++/credentials.h", + "include/grpc++/generic_stub.h", + "include/grpc++/impl/call.h", + "include/grpc++/impl/client_unary_call.h", + "include/grpc++/impl/internal_stub.h", + "include/grpc++/impl/rpc_method.h", + "include/grpc++/impl/rpc_service_method.h", + "include/grpc++/impl/service_type.h", + "include/grpc++/server.h", + "include/grpc++/server_builder.h", + "include/grpc++/server_context.h", + "include/grpc++/server_credentials.h", + "include/grpc++/slice.h", + "include/grpc++/status.h", + "include/grpc++/status_code_enum.h", + "include/grpc++/stream.h", + "include/grpc++/thread_pool_interface.h", + ], + includes = [ + "include", + ".", + ], + deps = [ + "//external:protobuf_clib", + ":gpr", + ":grpc", + ], +) + + +cc_library( + name = "grpc++_unsecure", + srcs = [ + "src/cpp/client/channel.h", + "src/cpp/proto/proto_utils.h", + "src/cpp/server/thread_pool.h", + "src/cpp/util/time.h", + "src/cpp/client/channel.cc", + "src/cpp/client/channel_arguments.cc", + "src/cpp/client/client_context.cc", + "src/cpp/client/client_unary_call.cc", + "src/cpp/client/create_channel.cc", + "src/cpp/client/credentials.cc", + "src/cpp/client/generic_stub.cc", + "src/cpp/client/insecure_credentials.cc", + "src/cpp/client/internal_stub.cc", + "src/cpp/common/call.cc", + "src/cpp/common/completion_queue.cc", + "src/cpp/common/rpc_method.cc", + "src/cpp/proto/proto_utils.cc", + "src/cpp/server/async_generic_service.cc", + "src/cpp/server/insecure_server_credentials.cc", + "src/cpp/server/server.cc", + "src/cpp/server/server_builder.cc", + "src/cpp/server/server_context.cc", + "src/cpp/server/server_credentials.cc", + "src/cpp/server/thread_pool.cc", + "src/cpp/util/byte_buffer.cc", + "src/cpp/util/slice.cc", + "src/cpp/util/status.cc", + "src/cpp/util/time.cc", + ], + hdrs = [ + "include/grpc++/async_generic_service.h", + "include/grpc++/async_unary_call.h", + "include/grpc++/byte_buffer.h", + "include/grpc++/channel_arguments.h", + "include/grpc++/channel_interface.h", + "include/grpc++/client_context.h", + "include/grpc++/completion_queue.h", + "include/grpc++/config.h", + "include/grpc++/create_channel.h", + "include/grpc++/credentials.h", + "include/grpc++/generic_stub.h", + "include/grpc++/impl/call.h", + "include/grpc++/impl/client_unary_call.h", + "include/grpc++/impl/internal_stub.h", + "include/grpc++/impl/rpc_method.h", + "include/grpc++/impl/rpc_service_method.h", + "include/grpc++/impl/service_type.h", + "include/grpc++/server.h", + "include/grpc++/server_builder.h", + "include/grpc++/server_context.h", + "include/grpc++/server_credentials.h", + "include/grpc++/slice.h", + "include/grpc++/status.h", + "include/grpc++/status_code_enum.h", + "include/grpc++/stream.h", + "include/grpc++/thread_pool_interface.h", + ], + includes = [ + "include", + ".", + ], + deps = [ + "//external:protobuf_clib", + ":gpr", + ":grpc_unsecure", + ], +) + + +cc_library( + name = "grpc_plugin_support", + srcs = [ + "src/compiler/config.h", + "src/compiler/cpp_generator.h", + "src/compiler/cpp_generator_helpers.h", + "src/compiler/generator_helpers.h", + "src/compiler/objective_c_generator.h", + "src/compiler/objective_c_generator_helpers.h", + "src/compiler/python_generator.h", + "src/compiler/ruby_generator.h", + "src/compiler/ruby_generator_helpers-inl.h", + "src/compiler/ruby_generator_map-inl.h", + "src/compiler/ruby_generator_string-inl.h", + "src/compiler/cpp_generator.cc", + "src/compiler/objective_c_generator.cc", + "src/compiler/python_generator.cc", + "src/compiler/ruby_generator.cc", + ], + hdrs = [ + ], + includes = [ + "include", + ".", + ], + deps = [ + "//external:protobuf_compiler", + ], +) + + +cc_library( + name = "grpc_csharp_ext", + srcs = [ + "src/csharp/ext/grpc_csharp_ext.c", + ], + hdrs = [ + ], + includes = [ + "include", + ".", + ], + deps = [ + ":gpr", + ":grpc", + ], +) + + + +cc_binary( + name = "grpc_cpp_plugin", + srcs = [ + "src/compiler/cpp_plugin.cc", + ], + deps = [ + "//external:protobuf_compiler", + ":grpc_plugin_support", + ], +) + + +cc_binary( + name = "grpc_objective_c_plugin", + srcs = [ + "src/compiler/objective_c_plugin.cc", + ], + deps = [ + "//external:protobuf_compiler", + ":grpc_plugin_support", + ], +) + + +cc_binary( + name = "grpc_python_plugin", + srcs = [ + "src/compiler/python_plugin.cc", + ], + deps = [ + "//external:protobuf_compiler", + ":grpc_plugin_support", + ], +) + + +cc_binary( + name = "grpc_ruby_plugin", + srcs = [ + "src/compiler/ruby_plugin.cc", + ], + deps = [ + "//external:protobuf_compiler", + ":grpc_plugin_support", + ], +) + + + + + @@ -94,6 +94,15 @@ CPPFLAGS_dbg = -O0 LDFLAGS_dbg = DEFINES_dbg = _DEBUG DEBUG +VALID_CONFIG_mutrace = 1 +CC_mutrace = $(DEFAULT_CC) +CXX_mutrace = $(DEFAULT_CXX) +LD_mutrace = $(DEFAULT_CC) +LDXX_mutrace = $(DEFAULT_CXX) +CPPFLAGS_mutrace = -O0 +LDFLAGS_mutrace = -rdynamic +DEFINES_mutrace = _DEBUG DEBUG + VALID_CONFIG_valgrind = 1 REQUIRE_CUSTOM_LIBRARIES_valgrind = 1 CC_valgrind = $(DEFAULT_CC) @@ -218,7 +227,6 @@ ifeq ($(HAS_CXX11),true) CXXFLAGS += -std=c++11 else CXXFLAGS += -std=c++0x -DEFINES += GRPC_OLD_CXX endif CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter LDFLAGS += -g @@ -276,7 +284,7 @@ E = @echo Q = @ endif -VERSION = 0.5.0.0 +VERSION = 0.6.0.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) @@ -447,7 +455,7 @@ endif .SECONDARY = %.pb.h %.pb.cc -PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin +PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin ifeq ($(DEP_MISSING),) all: static shared plugins dep_error: @@ -616,10 +624,14 @@ transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test +cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test credentials_test: $(BINDIR)/$(CONFIG)/credentials_test +cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test end2end_test: $(BINDIR)/$(CONFIG)/end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test +grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli grpc_cpp_plugin: $(BINDIR)/$(CONFIG)/grpc_cpp_plugin +grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin interop_client: $(BINDIR)/$(CONFIG)/interop_client @@ -629,6 +641,7 @@ pubsub_client: $(BINDIR)/$(CONFIG)/pubsub_client pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test qps_driver: $(BINDIR)/$(CONFIG)/qps_driver +qps_smoke_test: $(BINDIR)/$(CONFIG)/qps_smoke_test qps_worker: $(BINDIR)/$(CONFIG)/qps_worker status_test: $(BINDIR)/$(CONFIG)/status_test thread_pool_test: $(BINDIR)/$(CONFIG)/thread_pool_test @@ -1069,7 +1082,7 @@ buildtests: buildtests_c buildtests_cxx buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test -buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test +buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_smoke_test $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test test: test_c test_cxx @@ -1901,8 +1914,12 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/async_end2end_test || ( echo test async_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing channel_arguments_test" $(Q) $(BINDIR)/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 ) + $(E) "[RUN] Testing cli_call_test" + $(Q) $(BINDIR)/$(CONFIG)/cli_call_test || ( echo test cli_call_test failed ; exit 1 ) $(E) "[RUN] Testing credentials_test" $(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_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 end2end_test" $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" @@ -1985,92 +2002,152 @@ endif ifeq ($(NO_PROTOC),true) $(GENDIR)/examples/pubsub/empty.pb.cc: protoc_dep_error +$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: protoc_dep_error else $(GENDIR)/examples/pubsub/empty.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/examples/pubsub/empty.grpc.pb.cc: examples/pubsub/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/examples/pubsub/label.pb.cc: protoc_dep_error +$(GENDIR)/examples/pubsub/label.grpc.pb.cc: protoc_dep_error else $(GENDIR)/examples/pubsub/label.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/examples/pubsub/label.grpc.pb.cc: examples/pubsub/label.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/examples/pubsub/pubsub.pb.cc: protoc_dep_error +$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: protoc_dep_error else $(GENDIR)/examples/pubsub/pubsub.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc: examples/pubsub/pubsub.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/interop/empty.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/interop/empty.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/interop/empty.grpc.pb.cc: test/cpp/interop/empty.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/interop/messages.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/interop/messages.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/interop/messages.grpc.pb.cc: test/cpp/interop/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/interop/test.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/interop/test.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/interop/test.grpc.pb.cc: test/cpp/interop/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/qps/qpstest.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/qps/qpstest.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc: test/cpp/qps/qpstest.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/util/echo.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/util/echo.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/util/echo.grpc.pb.cc: test/cpp/util/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/util/echo_duplicate.grpc.pb.cc: test/cpp/util/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) $(GENDIR)/test/cpp/util/messages.pb.cc: protoc_dep_error +$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: protoc_dep_error else $(GENDIR)/test/cpp/util/messages.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/test/cpp/util/messages.grpc.pb.cc: test/cpp/util/messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif @@ -2147,10 +2224,11 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(prefix)/lib/gpr.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr-imp.a $(prefix)/lib/libgpr-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgpr.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so.0 $(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so endif endif @@ -2160,10 +2238,11 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(prefix)/lib/grpc.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc-imp.a $(prefix)/lib/libgrpc-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so.0 $(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so endif endif @@ -2173,10 +2252,11 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc_unsecure.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure-imp.a $(prefix)/lib/libgrpc_unsecure-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc_unsecure.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so.0 $(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so endif endif @@ -2194,10 +2274,11 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(prefix)/lib/grpc++.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++-imp.a $(prefix)/lib/libgrpc++-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc++.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so.0 $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so endif endif @@ -2207,10 +2288,11 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so.0 $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so endif endif @@ -2228,10 +2310,11 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/grpc_csharp_ext.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext-imp.a $(prefix)/lib/libgrpc_csharp_ext-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing libgrpc_csharp_ext.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so.0 $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so endif endif @@ -2250,6 +2333,8 @@ else $(Q) $(INSTALL) -d $(prefix)/bin $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(prefix)/bin/grpc_cpp_plugin $(Q) $(INSTALL) -d $(prefix)/bin + $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(prefix)/bin/grpc_objective_c_plugin + $(Q) $(INSTALL) -d $(prefix)/bin $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_python_plugin $(prefix)/bin/grpc_python_plugin $(Q) $(INSTALL) -d $(prefix)/bin $(Q) $(INSTALL) $(BINDIR)/$(CONFIG)/grpc_ruby_plugin $(prefix)/bin/grpc_ruby_plugin @@ -2292,6 +2377,7 @@ LIBGPR_SRC = \ src/core/support/alloc.c \ src/core/support/cancellable.c \ src/core/support/cmdline.c \ + src/core/support/cpu_iphone.c \ src/core/support/cpu_linux.c \ src/core/support/cpu_posix.c \ src/core/support/cpu_windows.c \ @@ -2317,6 +2403,7 @@ LIBGPR_SRC = \ src/core/support/sync.c \ src/core/support/sync_posix.c \ src/core/support/sync_win32.c \ + src/core/support/thd.c \ src/core/support/thd_posix.c \ src/core/support/thd_win32.c \ src/core/support/time.c \ @@ -2331,6 +2418,7 @@ PUBLIC_HEADERS_C += \ include/grpc/support/atm_win32.h \ include/grpc/support/cancellable_platform.h \ include/grpc/support/cmdline.h \ + include/grpc/support/cpu.h \ include/grpc/support/histogram.h \ include/grpc/support/host_port.h \ include/grpc/support/log.h \ @@ -2369,7 +2457,7 @@ $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT): $(LIBGPR_OBJS) $(ZLIB_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS) + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgpr.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS) else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgpr.so.0 -o $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBGPR_OBJS) $(LDLIBS) $(Q) ln -sf libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgpr.so.0 @@ -2384,6 +2472,7 @@ endif $(OBJDIR)/$(CONFIG)/src/core/support/alloc.o: $(OBJDIR)/$(CONFIG)/src/core/support/cancellable.o: $(OBJDIR)/$(CONFIG)/src/core/support/cmdline.o: +$(OBJDIR)/$(CONFIG)/src/core/support/cpu_iphone.o: $(OBJDIR)/$(CONFIG)/src/core/support/cpu_linux.o: $(OBJDIR)/$(CONFIG)/src/core/support/cpu_posix.o: $(OBJDIR)/$(CONFIG)/src/core/support/cpu_windows.o: @@ -2409,6 +2498,7 @@ $(OBJDIR)/$(CONFIG)/src/core/support/string_win32.o: $(OBJDIR)/$(CONFIG)/src/core/support/sync.o: $(OBJDIR)/$(CONFIG)/src/core/support/sync_posix.o: $(OBJDIR)/$(CONFIG)/src/core/support/sync_win32.o: +$(OBJDIR)/$(CONFIG)/src/core/support/thd.o: $(OBJDIR)/$(CONFIG)/src/core/support/thd_posix.o: $(OBJDIR)/$(CONFIG)/src/core/support/thd_win32.o: $(OBJDIR)/$(CONFIG)/src/core/support/time.o: @@ -2547,6 +2637,7 @@ LIBGRPC_SRC = \ src/core/surface/byte_buffer_reader.c \ src/core/surface/call.c \ src/core/surface/call_details.c \ + src/core/surface/call_log_batch.c \ src/core/surface/channel.c \ src/core/surface/channel_create.c \ src/core/surface/client.c \ @@ -2585,6 +2676,7 @@ PUBLIC_HEADERS_C += \ include/grpc/byte_buffer.h \ include/grpc/byte_buffer_reader.h \ include/grpc/grpc.h \ + include/grpc/grpc_http.h \ include/grpc/status.h \ LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC)))) @@ -2692,6 +2784,7 @@ src/core/surface/byte_buffer_queue.c: $(OPENSSL_DEP) src/core/surface/byte_buffer_reader.c: $(OPENSSL_DEP) src/core/surface/call.c: $(OPENSSL_DEP) src/core/surface/call_details.c: $(OPENSSL_DEP) +src/core/surface/call_log_batch.c: $(OPENSSL_DEP) src/core/surface/channel.c: $(OPENSSL_DEP) src/core/surface/channel_create.c: $(OPENSSL_DEP) src/core/surface/client.c: $(OPENSSL_DEP) @@ -2754,7 +2847,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT): $(LIBGRPC_OBJS) $(ZLIB_DEP) $(LIBDIR $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBGRPC_OBJS) $(LDLIBS) $(LDLIBS_SECURE) $(OPENSSL_MERGE_LIBS) -lgpr $(Q) ln -sf libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.so.0 @@ -2854,6 +2947,7 @@ $(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_queue.o: $(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_reader.o: $(OBJDIR)/$(CONFIG)/src/core/surface/call.o: $(OBJDIR)/$(CONFIG)/src/core/surface/call_details.o: +$(OBJDIR)/$(CONFIG)/src/core/surface/call_log_batch.o: $(OBJDIR)/$(CONFIG)/src/core/surface/channel.o: $(OBJDIR)/$(CONFIG)/src/core/surface/channel_create.o: $(OBJDIR)/$(CONFIG)/src/core/surface/client.o: @@ -3029,6 +3123,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/surface/byte_buffer_reader.c \ src/core/surface/call.c \ src/core/surface/call_details.c \ + src/core/surface/call_log_batch.c \ src/core/surface/channel.c \ src/core/surface/channel_create.c \ src/core/surface/client.c \ @@ -3066,6 +3161,7 @@ PUBLIC_HEADERS_C += \ include/grpc/byte_buffer.h \ include/grpc/byte_buffer_reader.h \ include/grpc/grpc.h \ + include/grpc/grpc_http.h \ include/grpc/status.h \ LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC)))) @@ -3091,7 +3187,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT): $(LIBGRPC_UNSECURE_OBJS) $( $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBGRPC_UNSECURE_OBJS) $(LDLIBS) -lgpr $(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.so.0 @@ -3167,6 +3263,7 @@ $(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_queue.o: $(OBJDIR)/$(CONFIG)/src/core/surface/byte_buffer_reader.o: $(OBJDIR)/$(CONFIG)/src/core/surface/call.o: $(OBJDIR)/$(CONFIG)/src/core/surface/call_details.o: +$(OBJDIR)/$(CONFIG)/src/core/surface/call_log_batch.o: $(OBJDIR)/$(CONFIG)/src/core/surface/channel.o: $(OBJDIR)/$(CONFIG)/src/core/surface/channel_create.o: $(OBJDIR)/$(CONFIG)/src/core/surface/client.o: @@ -3210,6 +3307,7 @@ LIBGRPC++_SRC = \ src/cpp/client/client_unary_call.cc \ src/cpp/client/create_channel.cc \ src/cpp/client/credentials.cc \ + src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/internal_stub.cc \ src/cpp/common/call.cc \ @@ -3239,12 +3337,19 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/config.h \ include/grpc++/create_channel.h \ include/grpc++/credentials.h \ + include/grpc++/generic_stub.h \ include/grpc++/impl/call.h \ include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/internal_stub.h \ include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_service_method.h \ include/grpc++/impl/service_type.h \ + include/grpc++/impl/sync.h \ + include/grpc++/impl/sync_cxx11.h \ + include/grpc++/impl/sync_no_cxx11.h \ + include/grpc++/impl/thd.h \ + include/grpc++/impl/thd_cxx11.h \ + include/grpc++/impl/thd_no_cxx11.h \ include/grpc++/server.h \ include/grpc++/server_builder.h \ include/grpc++/server_context.h \ @@ -3297,6 +3402,7 @@ src/cpp/client/client_context.cc: $(OPENSSL_DEP) src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP) src/cpp/client/create_channel.cc: $(OPENSSL_DEP) src/cpp/client/credentials.cc: $(OPENSSL_DEP) +src/cpp/client/generic_stub.cc: $(OPENSSL_DEP) src/cpp/client/insecure_credentials.cc: $(OPENSSL_DEP) src/cpp/client/internal_stub.cc: $(OPENSSL_DEP) src/cpp/common/call.cc: $(OPENSSL_DEP) @@ -3337,7 +3443,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(LI $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc else $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++.so.0 @@ -3363,6 +3469,7 @@ $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/generic_stub.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: @@ -3383,9 +3490,10 @@ $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: LIBGRPC++_TEST_UTIL_SRC = \ - $(GENDIR)/test/cpp/util/messages.pb.cc \ - $(GENDIR)/test/cpp/util/echo.pb.cc \ - $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc \ + $(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 \ + test/cpp/util/cli_call.cc \ test/cpp/util/create_test_channel.cc \ @@ -3416,6 +3524,7 @@ ifneq ($(OPENSSL_DEP),) test/cpp/util/messages.proto: $(OPENSSL_DEP) test/cpp/util/echo.proto: $(OPENSSL_DEP) test/cpp/util/echo_duplicate.proto: $(OPENSSL_DEP) +test/cpp/util/cli_call.cc: $(OPENSSL_DEP) test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP) endif @@ -3444,7 +3553,8 @@ endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc +$(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 LIBGRPC++_UNSECURE_SRC = \ @@ -3454,6 +3564,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/client/client_unary_call.cc \ src/cpp/client/create_channel.cc \ src/cpp/client/credentials.cc \ + src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/client/internal_stub.cc \ src/cpp/common/call.cc \ @@ -3483,12 +3594,19 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/config.h \ include/grpc++/create_channel.h \ include/grpc++/credentials.h \ + include/grpc++/generic_stub.h \ include/grpc++/impl/call.h \ include/grpc++/impl/client_unary_call.h \ include/grpc++/impl/internal_stub.h \ include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_service_method.h \ include/grpc++/impl/service_type.h \ + include/grpc++/impl/sync.h \ + include/grpc++/impl/sync_cxx11.h \ + include/grpc++/impl/sync_no_cxx11.h \ + include/grpc++/impl/thd.h \ + include/grpc++/impl/thd_cxx11.h \ + include/grpc++/impl/thd_no_cxx11.h \ include/grpc++/server.h \ include/grpc++/server_builder.h \ include/grpc++/server_context.h \ @@ -3536,7 +3654,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc++_unsecure.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure else $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so.0 @@ -3556,6 +3674,7 @@ $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/generic_stub.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: @@ -3575,10 +3694,52 @@ $(OBJDIR)/$(CONFIG)/src/cpp/util/status.o: $(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: +LIBGRPC_PLUGIN_SUPPORT_SRC = \ + src/compiler/cpp_generator.cc \ + src/compiler/objective_c_generator.cc \ + src/compiler/python_generator.cc \ + src/compiler/ruby_generator.cc \ + + +LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC)))) + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC_PLUGIN_SUPPORT_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a + $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a +endif + + + + +endif + +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC_PLUGIN_SUPPORT_OBJS:.o=.dep) +endif + +$(OBJDIR)/$(CONFIG)/src/compiler/cpp_generator.o: +$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_generator.o: +$(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o: +$(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o: + + LIBPUBSUB_CLIENT_LIB_SRC = \ - $(GENDIR)/examples/pubsub/label.pb.cc \ - $(GENDIR)/examples/pubsub/empty.pb.cc \ - $(GENDIR)/examples/pubsub/pubsub.pb.cc \ + $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc \ + $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc \ + $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc \ examples/pubsub/publisher.cc \ examples/pubsub/subscriber.cc \ @@ -3639,13 +3800,14 @@ endif -$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc -$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc +$(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc $(GENDIR)/examples/pubsub/pubsub.grpc.pb.cc LIBQPS_SRC = \ - $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ + $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \ test/cpp/qps/driver.cc \ + test/cpp/qps/report.cc \ test/cpp/qps/timer.cc \ @@ -3675,6 +3837,7 @@ ifneq ($(OPENSSL_DEP),) # otherwise parallel compilation will fail if a source is compiled first. test/cpp/qps/qpstest.proto: $(OPENSSL_DEP) test/cpp/qps/driver.cc: $(OPENSSL_DEP) +test/cpp/qps/report.cc: $(OPENSSL_DEP) test/cpp/qps/timer.cc: $(OPENSSL_DEP) endif @@ -3701,8 +3864,9 @@ endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc -$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc LIBGRPC_CSHARP_EXT_SRC = \ @@ -3754,7 +3918,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT): $(LIBGRPC_CSHARP_EXT_OBJS) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc + $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name libgrpc_csharp_ext.$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc else $(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_csharp_ext.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(LIBGRPC_CSHARP_EXT_OBJS) $(LDLIBS) -lgpr -lgrpc $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.so.0 @@ -7971,6 +8135,48 @@ endif endif +CLI_CALL_TEST_SRC = \ + test/cpp/util/cli_call_test.cc \ + +CLI_CALL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CLI_CALL_TEST_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL with ALPN. + +$(BINDIR)/$(CONFIG)/cli_call_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)/cli_call_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cli_call_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_cli_call_test: $(CLI_CALL_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CLI_CALL_TEST_OBJS:.o=.dep) +endif +endif + + CREDENTIALS_TEST_SRC = \ test/cpp/client/credentials_test.cc \ @@ -8013,6 +8219,48 @@ endif endif +CXX_TIME_TEST_SRC = \ + test/cpp/util/time_test.cc \ + +CXX_TIME_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CXX_TIME_TEST_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL with ALPN. + +$(BINDIR)/$(CONFIG)/cxx_time_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)/cxx_time_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/cxx_time_test: $(PROTOBUF_DEP) $(CXX_TIME_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) $(CXX_TIME_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/cxx_time_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/util/time_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_cxx_time_test: $(CXX_TIME_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CXX_TIME_TEST_OBJS:.o=.dep) +endif +endif + + END2END_TEST_SRC = \ test/cpp/end2end/end2end_test.cc \ @@ -8097,8 +8345,49 @@ endif endif +GRPC_CLI_SRC = \ + test/cpp/util/grpc_cli.cc \ + +GRPC_CLI_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CLI_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL with ALPN. + +$(BINDIR)/$(CONFIG)/grpc_cli: 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)/grpc_cli: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_cli + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GRPC_CLI_OBJS:.o=.dep) +endif +endif + + GRPC_CPP_PLUGIN_SRC = \ - src/compiler/cpp_generator.cc \ src/compiler/cpp_plugin.cc \ GRPC_CPP_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_CPP_PLUGIN_SRC)))) @@ -8112,15 +8401,14 @@ $(BINDIR)/$(CONFIG)/grpc_cpp_plugin: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: $(PROTOBUF_DEP) $(GRPC_CPP_PLUGIN_OBJS) +$(BINDIR)/$(CONFIG)/grpc_cpp_plugin: $(PROTOBUF_DEP) $(GRPC_CPP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(E) "[HOSTLD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_CPP_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_cpp_plugin + $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_CPP_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_cpp_plugin endif -$(OBJDIR)/$(CONFIG)/src/compiler/cpp_generator.o: -$(OBJDIR)/$(CONFIG)/src/compiler/cpp_plugin.o: +$(OBJDIR)/$(CONFIG)/src/compiler/cpp_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a deps_grpc_cpp_plugin: $(GRPC_CPP_PLUGIN_OBJS:.o=.dep) @@ -8129,8 +8417,37 @@ ifneq ($(NO_DEPS),true) endif +GRPC_OBJECTIVE_C_PLUGIN_SRC = \ + src/compiler/objective_c_plugin.cc \ + +GRPC_OBJECTIVE_C_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_OBJECTIVE_C_PLUGIN_SRC)))) + + +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)/grpc_objective_c_plugin: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpc_objective_c_plugin: $(PROTOBUF_DEP) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a + $(E) "[HOSTLD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_OBJECTIVE_C_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin + +endif + +$(OBJDIR)/$(CONFIG)/src/compiler/objective_c_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a + +deps_grpc_objective_c_plugin: $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep) + +ifneq ($(NO_DEPS),true) +-include $(GRPC_OBJECTIVE_C_PLUGIN_OBJS:.o=.dep) +endif + + GRPC_PYTHON_PLUGIN_SRC = \ - src/compiler/python_generator.cc \ src/compiler/python_plugin.cc \ GRPC_PYTHON_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_PYTHON_PLUGIN_SRC)))) @@ -8144,15 +8461,14 @@ $(BINDIR)/$(CONFIG)/grpc_python_plugin: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS) +$(BINDIR)/$(CONFIG)/grpc_python_plugin: $(PROTOBUF_DEP) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(E) "[HOSTLD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin + $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_PYTHON_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_python_plugin endif -$(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o: -$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o: +$(OBJDIR)/$(CONFIG)/src/compiler/python_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a deps_grpc_python_plugin: $(GRPC_PYTHON_PLUGIN_OBJS:.o=.dep) @@ -8162,7 +8478,6 @@ endif GRPC_RUBY_PLUGIN_SRC = \ - src/compiler/ruby_generator.cc \ src/compiler/ruby_plugin.cc \ GRPC_RUBY_PLUGIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_RUBY_PLUGIN_SRC)))) @@ -8176,15 +8491,14 @@ $(BINDIR)/$(CONFIG)/grpc_ruby_plugin: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: $(PROTOBUF_DEP) $(GRPC_RUBY_PLUGIN_OBJS) +$(BINDIR)/$(CONFIG)/grpc_ruby_plugin: $(PROTOBUF_DEP) $(GRPC_RUBY_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(E) "[HOSTLD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_RUBY_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_ruby_plugin + $(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GRPC_RUBY_PLUGIN_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(HOST_LDLIBSXX) $(HOST_LDLIBS_PROTOC) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o $(BINDIR)/$(CONFIG)/grpc_ruby_plugin endif -$(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o: -$(OBJDIR)/$(CONFIG)/src/compiler/ruby_plugin.o: +$(OBJDIR)/$(CONFIG)/src/compiler/ruby_plugin.o: $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a deps_grpc_ruby_plugin: $(GRPC_RUBY_PLUGIN_OBJS:.o=.dep) @@ -8194,9 +8508,9 @@ endif INTEROP_CLIENT_SRC = \ - $(GENDIR)/test/cpp/interop/empty.pb.cc \ - $(GENDIR)/test/cpp/interop/messages.pb.cc \ - $(GENDIR)/test/cpp/interop/test.pb.cc \ + $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \ test/cpp/interop/client.cc \ INTEROP_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_CLIENT_SRC)))) @@ -8242,9 +8556,9 @@ endif INTEROP_SERVER_SRC = \ - $(GENDIR)/test/cpp/interop/empty.pb.cc \ - $(GENDIR)/test/cpp/interop/messages.pb.cc \ - $(GENDIR)/test/cpp/interop/test.pb.cc \ + $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \ + $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \ test/cpp/interop/server.cc \ INTEROP_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_SERVER_SRC)))) @@ -8499,6 +8813,48 @@ endif endif +QPS_SMOKE_TEST_SRC = \ + test/cpp/qps/smoke_test.cc \ + +QPS_SMOKE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_SMOKE_TEST_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL with ALPN. + +$(BINDIR)/$(CONFIG)/qps_smoke_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)/qps_smoke_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/qps_smoke_test: $(PROTOBUF_DEP) $(QPS_SMOKE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(QPS_SMOKE_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/qps_smoke_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/qps/smoke_test.o: $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_qps_smoke_test: $(QPS_SMOKE_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(QPS_SMOKE_TEST_OBJS:.o=.dep) +endif +endif + + QPS_WORKER_SRC = \ test/cpp/qps/client_async.cc \ test/cpp/qps/client_sync.cc \ @@ -5,6 +5,10 @@ Copyright 2015 Google Inc. +#Documentation + +You can find more detailed documentation and examples in the [grpc-common repository](http://github.com/grpc/grpc-common). + #Installation See grpc/INSTALL for installation instructions for various platforms. @@ -25,10 +29,6 @@ of shared C core library [src/core] (src/core). Java source code is in [grpc-java] (http://github.com/grpc/grpc-java) repository. Go source code is in [grpc-go] (http://github.com/grpc/grpc-go) repository. -#Documentation - -You can find more detailed documentation and examples in the [grpc-common repository](http://github.com/grpc/grpc-common). - #Current Status of libraries Libraries in different languages are in different state of development. We are seeking contributions for all of these libraries. diff --git a/build.json b/build.json index 999e140c5a..0a7b81d5f5 100644 --- a/build.json +++ b/build.json @@ -3,7 +3,7 @@ "#": "The public version number of the library.", "version": { "major": 0, - "minor": 5, + "minor": 6, "micro": 0, "build": 0 } @@ -22,12 +22,19 @@ "include/grpc++/config.h", "include/grpc++/create_channel.h", "include/grpc++/credentials.h", + "include/grpc++/generic_stub.h", "include/grpc++/impl/call.h", "include/grpc++/impl/client_unary_call.h", "include/grpc++/impl/internal_stub.h", "include/grpc++/impl/rpc_method.h", "include/grpc++/impl/rpc_service_method.h", "include/grpc++/impl/service_type.h", + "include/grpc++/impl/sync.h", + "include/grpc++/impl/sync_cxx11.h", + "include/grpc++/impl/sync_no_cxx11.h", + "include/grpc++/impl/thd.h", + "include/grpc++/impl/thd_cxx11.h", + "include/grpc++/impl/thd_no_cxx11.h", "include/grpc++/server.h", "include/grpc++/server_builder.h", "include/grpc++/server_context.h", @@ -51,6 +58,7 @@ "src/cpp/client/client_unary_call.cc", "src/cpp/client/create_channel.cc", "src/cpp/client/credentials.cc", + "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/client/internal_stub.cc", "src/cpp/common/call.cc", @@ -76,6 +84,7 @@ "include/grpc/byte_buffer.h", "include/grpc/byte_buffer_reader.h", "include/grpc/grpc.h", + "include/grpc/grpc_http.h", "include/grpc/status.h" ], "headers": [ @@ -143,6 +152,7 @@ "src/core/surface/init.h", "src/core/surface/server.h", "src/core/surface/surface_trace.h", + "src/core/transport/chttp2/alpn.h", "src/core/transport/chttp2/bin_encoder.h", "src/core/transport/chttp2/frame.h", "src/core/transport/chttp2/frame_data.h", @@ -230,6 +240,7 @@ "src/core/surface/byte_buffer_reader.c", "src/core/surface/call.c", "src/core/surface/call_details.c", + "src/core/surface/call_log_batch.c", "src/core/surface/channel.c", "src/core/surface/channel_create.c", "src/core/surface/client.c", @@ -278,6 +289,7 @@ "include/grpc/support/atm_win32.h", "include/grpc/support/cancellable_platform.h", "include/grpc/support/cmdline.h", + "include/grpc/support/cpu.h", "include/grpc/support/histogram.h", "include/grpc/support/host_port.h", "include/grpc/support/log.h", @@ -305,6 +317,7 @@ "src/core/support/alloc.c", "src/core/support/cancellable.c", "src/core/support/cmdline.c", + "src/core/support/cpu_iphone.c", "src/core/support/cpu_linux.c", "src/core/support/cpu_posix.c", "src/core/support/cpu_windows.c", @@ -330,6 +343,7 @@ "src/core/support/sync.c", "src/core/support/sync_posix.c", "src/core/support/sync_win32.c", + "src/core/support/thd.c", "src/core/support/thd_posix.c", "src/core/support/thd_win32.c", "src/core/support/time.c", @@ -343,6 +357,9 @@ "name": "gpr_test_util", "build": "private", "language": "c", + "headers": [ + "test/core/util/test_config.h" + ], "src": [ "test/core/util/test_config.c" ], @@ -367,6 +384,7 @@ "src/core/security/base64.h", "src/core/security/credentials.h", "src/core/security/json_token.h", + "src/core/security/secure_endpoint.h", "src/core/security/secure_transport_setup.h", "src/core/security/security_context.h", "src/core/tsi/fake_transport_security.h", @@ -426,6 +444,7 @@ ], "deps": [ "gpr", + "gpr_test_util", "grpc" ], "vs_project_guid": "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}" @@ -451,6 +470,10 @@ "name": "grpc++", "build": "all", "language": "c++", + "headers": [ + "src/cpp/client/secure_credentials.h", + "src/cpp/server/secure_server_credentials.h" + ], "src": [ "src/cpp/client/secure_credentials.cc", "src/cpp/server/secure_server_credentials.cc" @@ -474,6 +497,7 @@ "test/cpp/util/messages.proto", "test/cpp/util/echo.proto", "test/cpp/util/echo_duplicate.proto", + "test/cpp/util/cli_call.cc", "test/cpp/util/create_test_channel.cc" ] }, @@ -492,6 +516,32 @@ "secure": "no" }, { + "name": "grpc_plugin_support", + "build": "protoc", + "language": "c++", + "headers": [ + "src/compiler/config.h", + "src/compiler/cpp_generator.h", + "src/compiler/cpp_generator_helpers.h", + "src/compiler/generator_helpers.h", + "src/compiler/objective_c_generator.h", + "src/compiler/objective_c_generator_helpers.h", + "src/compiler/python_generator.h", + "src/compiler/ruby_generator.h", + "src/compiler/ruby_generator_helpers-inl.h", + "src/compiler/ruby_generator_map-inl.h", + "src/compiler/ruby_generator_string-inl.h" + ], + "src": [ + "src/compiler/cpp_generator.cc", + "src/compiler/objective_c_generator.cc", + "src/compiler/python_generator.cc", + "src/compiler/ruby_generator.cc" + ], + "deps": [], + "secure": "no" + }, + { "name": "pubsub_client_lib", "build": "private", "language": "c++", @@ -514,11 +564,13 @@ "language": "c++", "headers": [ "test/cpp/qps/driver.h", + "test/cpp/qps/report.h", "test/cpp/qps/timer.h" ], "src": [ "test/cpp/qps/qpstest.proto", "test/cpp/qps/driver.cc", + "test/cpp/qps/report.cc", "test/cpp/qps/timer.cc" ] }, @@ -1676,6 +1728,22 @@ ] }, { + "name": "cli_call_test", + "build": "test", + "language": "c++", + "src": [ + "test/cpp/util/cli_call_test.cc" + ], + "deps": [ + "grpc++_test_util", + "grpc_test_util", + "grpc++", + "grpc", + "gpr_test_util", + "gpr" + ] + }, + { "name": "credentials_test", "build": "test", "language": "c++", @@ -1689,6 +1757,21 @@ ] }, { + "name": "cxx_time_test", + "build": "test", + "language": "c++", + "src": [ + "test/cpp/util/time_test.cc" + ], + "deps": [ + "grpc_test_util", + "grpc++", + "grpc", + "gpr_test_util", + "gpr" + ] + }, + { "name": "end2end_test", "build": "test", "language": "c++", @@ -1721,32 +1804,56 @@ ] }, { + "name": "grpc_cli", + "build": "test", + "run": false, + "language": "c++", + "src": [ + "test/cpp/util/grpc_cli.cc" + ], + "deps": [ + "grpc++_test_util", + "grpc_test_util", + "grpc++", + "grpc", + "gpr_test_util", + "gpr" + ] + }, + { "name": "grpc_cpp_plugin", "build": "protoc", "language": "c++", - "headers": [ - "src/compiler/cpp_generator.h", - "src/compiler/cpp_generator_helpers.h" - ], "src": [ - "src/compiler/cpp_generator.cc", "src/compiler/cpp_plugin.cc" ], - "deps": [], + "deps": [ + "grpc_plugin_support" + ], "secure": "no" }, { - "name": "grpc_python_plugin", + "name": "grpc_objective_c_plugin", "build": "protoc", "language": "c++", - "headers": [ - "src/compiler/python_generator.h" + "src": [ + "src/compiler/objective_c_plugin.cc" ], + "deps": [ + "grpc_plugin_support" + ], + "secure": "no" + }, + { + "name": "grpc_python_plugin", + "build": "protoc", + "language": "c++", "src": [ - "src/compiler/python_generator.cc", "src/compiler/python_plugin.cc" ], - "deps": [], + "deps": [ + "grpc_plugin_support" + ], "secure": "no" }, { @@ -1754,10 +1861,11 @@ "build": "protoc", "language": "c++", "src": [ - "src/compiler/ruby_generator.cc", "src/compiler/ruby_plugin.cc" ], - "deps": [], + "deps": [ + "grpc_plugin_support" + ], "secure": "no" }, { @@ -1884,6 +1992,24 @@ ] }, { + "name": "qps_smoke_test", + "build": "test", + "run": false, + "language": "c++", + "src": [ + "test/cpp/qps/smoke_test.cc" + ], + "deps": [ + "qps", + "grpc++_test_util", + "grpc_test_util", + "grpc++", + "grpc", + "gpr_test_util", + "gpr" + ] + }, + { "name": "qps_worker", "build": "test", "run": false, diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md new file mode 100644 index 0000000000..3f5ce37e1e --- /dev/null +++ b/doc/interop-test-descriptions.md @@ -0,0 +1,685 @@ +Interoperability Test Case Descriptions +======================================= + +Client and server use +[test.proto](https://github.com/grpc/grpc/blob/master/test/cpp/interop/test.proto) +and the [gRPC over HTTP/2 v2 +protocol](https://github.com/grpc/grpc-common/blob/master/PROTOCOL-HTTP2.md). + +Client +------ + +Clients implement test cases that test certain functionally. Each client is +provided the test case it is expected to run as a command-line parameter. Names +should be lowercase and without spaces. + +Clients should accept these arguments: +* --server_host=HOSTNAME + * The server host to connect to. For example, "localhost" or "127.0.0.1" +* --server_host_override=HOSTNAME + * The server host to claim to be connecting to, for use in TLS and HTTP/2 + :authority header. If unspecified, the value of --server_host will be + used +* --server_port=PORT + * The server port to connect to. For example, "8080" +* --test_case=TESTCASE + * The name of the test case to execute. For example, "empty_unary" +* --use_tls=BOOLEAN + * Whether to use a plaintext or encrypted connection +* --use_test_ca=BOOLEAN + * Whether to replace platform root CAs with + [ca.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/ca.pem) + as the CA root + +Clients must support TLS with ALPN. Clients must not disable certificate +checking. + +### empty_unary + +This test verifies that implementations support zero-size messages. Ideally, +client implementations would verify that the request and response were zero +bytes serialized, but this is generally prohibitive to perform, so is not +required. + +Server features: +* [EmptyCall][] + +Procedure: + 1. Client calls EmptyCall with the default Empty message + +Asserts: +* call was successful +* response is non-null + +*It may be possible to use UnaryCall instead of EmptyCall, but it is harder to +ensure that the proto serialized to zero bytes.* + +### large_unary + +This test verifies unary calls succeed in sending messages, and touches on flow +control (even if compression is enabled on the channel). + +Server features: +* [UnaryCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + +Asserts: +* call was successful +* response payload type is COMPRESSABLE +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### client_streaming + +This test verifies that client-only streaming succeeds. + +Server features: +* [StreamingInputCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls StreamingInputCall + 2. Client sends: + + ``` + { + payload:{ + body: 27182 bytes of zeros + } + } + ``` + 3. Client then sends: + + ``` + { + payload:{ + body: 8 bytes of zeros + } + } + ``` + 4. Client then sends: + + ``` + { + payload:{ + body: 1828 bytes of zeros + } + } + ``` + 5. Client then sends: + + ``` + { + payload:{ + body: 45904 bytes of zeros + } + } + ``` + 6. Client halfCloses + +Asserts: +* call was successful +* response aggregated_payload_size is 74922 + +### server_streaming + +This test verifies that server-only streaming succeeds. + +Server features: +* [StreamingOutputCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls StreamingOutputCall with: + + ``` + { + response_type:COMPRESSABLE + response_parameters:{ + size: 31415 + } + response_parameters:{ + size: 9 + } + response_parameters:{ + size: 2653 + } + response_parameters:{ + size: 58979 + } + } + ``` + +Asserts: +* call was successful +* exactly four responses +* response payloads are COMPRESSABLE +* response payload bodies are sized (in order): 31415, 9, 2653, 58979 +* clients are free to assert that the response payload body contents are zero + and comparing the entire response messages against golden responses + +### ping_pong + +This test verifies that full duplex bidi is supported. + +Server features: +* [FullDuplexCall][] +* [Compressable Payload][] + +Procedure: + 1. Client calls FullDuplexCall with: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 31415 + } + payload:{ + body: 27182 bytes of zeros + } + } + ``` + 2. After getting a reply, it sends: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 9 + } + payload:{ + body: 8 bytes of zeros + } + } + ``` + 3. After getting a reply, it sends: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 2653 + } + payload:{ + body: 1828 bytes of zeros + } + } + ``` + 4. After getting a reply, it sends: + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 58979 + } + payload:{ + body: 45904 bytes of zeros + } + } + ``` + +Asserts: +* call was successful +* exactly four responses +* response payloads are COMPRESSABLE +* response payload bodies are sized (in order): 31415, 9, 2653, 58979 +* clients are free to assert that the response payload body contents are zero + and comparing the entire response messages against golden responses + +### empty_stream + +This test verifies that streams support having zero-messages in both +directions. + +Server features: +* [FullDuplexCall][] + +Procedure: + 1. Client calls FullDuplexCall and then half-closes + +Asserts: +* call was successful +* exactly zero responses + +### compute_engine_creds + +Status: Not yet implementable + +This test is only for cloud-to-prod path. + +This test verifies unary calls succeed in sending messages while using Service +Credentials from GCE metadata server. The client instance needs to be created +with desired oauth scope. + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* SimpeResponse.username +* SimpleResponse.oauth_scope + +Procedure: + 1. Client sets flags default_service_account with GCE service account name and + oauth_scope with the oauth scope to use. + 2. Client configures channel to use GCECredentials + 3. Client calls UnaryCall on the channel with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + fill_username: true + fill_oauth_scope: true + } + ``` + +Asserts: +* call was successful +* received SimpleResponse.username equals FLAGS_default_service_account +* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### service_account_creds + +Status: Not yet implementable + +This test is only for cloud-to-prod path. + +This test verifies unary calls succeed in sending messages while using JWT +signing keys (redeemed for OAuth2 access tokens by the auth implementation) + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* SimpleResponse.username +* SimpleResponse.oauth_scope + +Procedure: + 1. Client sets flags service_account_key_file with the path to json key file, + oauth_scope to the oauth scope. + 2. Client configures the channel to use ServiceAccountCredentials. + 3. Client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + fill_username: true + fill_oauth_scope: true + } + ``` + +Asserts: +* call was successful +* received SimpleResponse.username is in the json key file read from + FLAGS_service_account_key_file +* received SimpleResponse.oauth_scope is in FLAGS_oauth_scope +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### jwt_token_creds + +Status: Not yet implementable + +This test is only for cloud-to-prod path. + +This test verifies unary calls succeed in sending messages while using JWT +token (created by the project's key file) + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* SimpleResponse.username +* SimpleResponse.oauth_scope + +Procedure: + 1. Client sets flags service_account_key_file with the path to json key file + 2. Client configures the channel to use JWTTokenCredentials. + 3. Client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + fill_username: true + } + ``` + +Asserts: +* call was successful +* received SimpleResponse.username is in the json key file read from + FLAGS_service_account_key_file +* response payload body is 314159 bytes in size +* clients are free to assert that the response payload body contents are zero + and comparing the entire response message against a golden response + +### Metadata (TODO: fix name) + +Status: Not yet implementable + +This test verifies that custom metadata in either binary or ascii format can be +sent in header and trailer. + +Server features: +* [UnaryCall][] +* [Compressable Payload][] +* Ability to receive custom metadata from client in header and send custom data + back to client in both header and trailer. (TODO: this is not defined) + +Procedure: + 1. While sending custom metadata (ascii + binary) in the header, client calls UnaryCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + +Asserts: +* call was successful +* custom metadata is echoed back in the response header. +* custom metadata is echoed back in the response trailer. + +### status_code_and_message + +Status: Not yet implementable + +This test verifies unary calls succeed in sending messages, and propagates back +status code and message sent along with the messages. + +Server features: +* [UnaryCall][] + +Procedure: + 1. Client calls UnaryCall with: + + ``` + { + response_status:{ + code: 2 + message: "test status message" + } + } + ``` + +Asserts: +* received status code is the same with sent code +* received status message is the same with sent message + +### unimplemented_method + +Status: Not yet implementable + +This test verifies calling unimplemented RPC method returns unimplemented +status. + +Procedure: +* Client calls UnimplementedCall with: + + ``` + { + response_type: COMPRESSABLE + response_size: 314159 + payload:{ + body: 271828 bytes of zeros + } + } + ``` + +Asserts: +* received status code is 12 (UNIMPLEMENTED) +* received status message is empty or null/unset + +### cancel_after_begin + +This test verifies that a request can be cancelled after metadata has been sent +but before payloads are sent. + +Server features: +* [StreamingInputCall][] + +Procedure: + 1. Client starts StreamingInputCall + 2. Client immediately cancels request + +Asserts: +* Call completed with status CANCELLED + +### cancel_after_first_response + +This test verifies that a request can be cancelled after receiving a message +from the server. + +Server features: +* [FullDuplexCall][] +* [Compressable Payload][] + +Procedure: + 1. Client starts FullDuplexCall with + + ``` + { + response_type: COMPRESSABLE + response_parameters:{ + size: 31415 + } + payload:{ + body: 27182 bytes of zeros + } + } + ``` + 2. After receiving a response, client cancels request + +Asserts: +* Call completed with status CANCELLED + +### concurrent_large_unary + +Status: TODO + +Client performs 1000 large_unary tests in parallel on the same channel. + +### Flow control. Pushback at client for large messages (TODO: fix name) + +Status: TODO + +This test verifies that a client sending faster than a server can drain sees +pushback (i.e., attempts to send succeed only after appropriate delays). + +### TODO Tests + +High priority: + +Propagation of status code and message (yangg) + +Cancel after sent headers (ctiller - done) + +Cancel after received first message (ctiller - done) + +Timeout after expire (zhaoq) + +Zero-message streams (ejona) + +Multiple thousand simultaneous calls on same Channel (ctiller - done) + +OAuth2 tokens + Service Credentials from GCE metadata server (GCE->prod only) +(abhishek) + +OAuth2 tokens + JWT signing key (GCE->prod only) (abhishek) + +Metadata: client headers, server headers + trailers, binary+ascii (chenw) + +Normal priority: + +Cancel before start (ctiller) + +Cancel after sent first message (ctiller) + +Cancel after received headers (ctiller) + +Timeout but completed before expire (zhaoq) + +Multiple thousand simultaneous calls timeout on same Channel (ctiller) + +Lower priority: + +Flow control. Pushback at client for large messages (abhishek) + +Flow control. Pushback at server for large messages (abhishek) + +Going over max concurrent streams doesn't fail (client controls itself) +(abhishek) + +RPC method not implemented (yangg) + +Multiple thousand simultaneous calls on different Channels (ctiller) + +Failed TLS hostname verification (ejona?) + +To priorize: + +Start streaming RPC but don't send any requests, server responds + +### Postponed Tests + +Resilience to buggy servers: These tests would verify that a client application +isn't affected negatively by the responses put on the wire by a buggy server +(e.g. the client library won't make the application crash). + +Reconnect after transport failure + +Reconnect backoff + +Fuzz testing + + +Server +------ + +Servers implement various named features for clients to test with. Server +features are orthogonal. If a server implements a feature, it is always +available for clients. Names are simple descriptions for developer +communication and tracking. + +Servers should accept these arguments: + +* --port=PORT + + * The port to listen on. For example, "8080" + +* --use_tls=BOOLEAN + + * Whether to use a plaintext or encrypted connection + +Servers must support TLS with ALPN. They should use +[server1.pem](https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/server1.pem) +for their certificate. + +### EmptyCall +[EmptyCall]: #emptycall + +Server implements EmptyCall which immediately returns the empty message. + +### UnaryCall +[UnaryCall]: #unarycall + +Server implements UnaryCall which immediately returns a SimpleResponse with a +payload body of size SimpleRequest.response_size bytes and type as appropriate +for the SimpleRequest.response_type. If the server does not support the +response_type, then it should fail the RPC with INVALID_ARGUMENT. + +If the request sets fill_username, the server should return the client username +it sees in field SimpleResponse.username. If the request sets fill_oauth_scope, +the server should return the oauth scope of the rpc in the form of "xapi_zoo" +in field SimpleResponse.oauth_scope. + +### StreamingInputCall +[StreamingInputCall]: #streaminginputcall + +Server implements StreamingInputCall which upon half close immediately returns +a StreamingInputCallResponse where aggregated_payload_size is the sum of all +request payload bodies received. + +### StreamingOutputCall +[StreamingOutputCall]: #streamingoutputcall + +Server implements StreamingOutputCall by replying, in order, with one +StreamingOutputCallResponses for each ResponseParameters in +StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a +payload body of size ResponseParameters.size bytes, as specified by its +respective ResponseParameters. After sending all responses, it closes with OK. + +### FullDuplexCall +[FullDuplexCall]: #fullduplexcall + +Server implements FullDuplexCall by replying, in order, with one +StreamingOutputCallResponses for each ResponseParameters in each +StreamingOutputCallRequest. Each StreamingOutputCallResponses should have a +payload body of size ResponseParameters.size bytes, as specified by its +respective ResponseParameters. After receiving half close and sending all +responses, it closes with OK. + +### Compressable Payload +[Compressable Payload]: #compressable-payload + +When the client requests COMPRESSABLE payload, the response includes a payload +of the size requested containing all zeros and the payload type is +COMPRESSABLE. + +### Observe ResponseParameters.interval_us +[Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us + +In StreamingOutputCall and FullDuplexCall, server delays sending a +StreamingOutputCallResponse by the ResponseParameters's interval_us for that +particular response, relative to the last response sent. That is, interval_us +acts like a sleep *before* sending the response and accumulates from one +response to the next. + +Interaction with flow control is unspecified. + +### Echo Auth Information + +Status: Pending + +If a SimpleRequest has fill_username=true and that request was successfully +authenticated, then the SimpleResponse should have username filled with the +canonical form of the authenticated source. The canonical form is dependent on +the authentication method, but is likely to be a base 10 integer identifier or +an email address. + +Discussion: + +Ideally, this would be communicated via metadata and not in the +request/response, but we want to use this test in code paths that don't yet +fully communicate metadata. diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc index 6f7737e247..cc5076f0a5 100644 --- a/examples/pubsub/main.cc +++ b/examples/pubsub/main.cc @@ -51,14 +51,14 @@ #include "examples/pubsub/subscriber.h" DEFINE_int32(server_port, 443, "Server port."); -DEFINE_string(server_host, - "pubsub-staging.googleapis.com", "Server host to connect to"); +DEFINE_string(server_host, "pubsub-staging.googleapis.com", + "Server host to connect to"); DEFINE_string(project_id, "", "GCE project id such as stoked-keyword-656"); // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. -namespace google { } -namespace gflags { } +namespace google {} +namespace gflags {} using namespace google; using namespace gflags; @@ -92,32 +92,32 @@ int main(int argc, char** argv) { grpc::string topic = ss.str(); ss.str(""); - ss << FLAGS_project_id << "/" << kSubscriptionName; + ss << FLAGS_project_id << "/" << kSubscriptionName; grpc::string subscription_name = ss.str(); // Clean up test topic and subcription if they exist before. grpc::string subscription_topic; - if (subscriber.GetSubscription( - subscription_name, &subscription_topic).IsOk()) { + if (subscriber.GetSubscription(subscription_name, &subscription_topic) + .IsOk()) { subscriber.DeleteSubscription(subscription_name); } if (publisher.GetTopic(topic).IsOk()) publisher.DeleteTopic(topic); grpc::Status s = publisher.CreateTopic(topic); - gpr_log(GPR_INFO, "Create topic returns code %d, %s", - s.code(), s.details().c_str()); + gpr_log(GPR_INFO, "Create topic returns code %d, %s", s.code(), + s.details().c_str()); GPR_ASSERT(s.IsOk()); s = publisher.GetTopic(topic); - gpr_log(GPR_INFO, "Get topic returns code %d, %s", - s.code(), s.details().c_str()); + gpr_log(GPR_INFO, "Get topic returns code %d, %s", s.code(), + s.details().c_str()); GPR_ASSERT(s.IsOk()); std::vector<grpc::string> topics; s = publisher.ListTopics(FLAGS_project_id, &topics); - gpr_log(GPR_INFO, "List topic returns code %d, %s", - s.code(), s.details().c_str()); + gpr_log(GPR_INFO, "List topic returns code %d, %s", s.code(), + s.details().c_str()); bool topic_found = false; for (unsigned int i = 0; i < topics.size(); i++) { if (topics[i] == topic) topic_found = true; @@ -127,27 +127,27 @@ int main(int argc, char** argv) { GPR_ASSERT(topic_found); s = subscriber.CreateSubscription(topic, subscription_name); - gpr_log(GPR_INFO, "create subscrption returns code %d, %s", - s.code(), s.details().c_str()); + gpr_log(GPR_INFO, "create subscrption returns code %d, %s", s.code(), + s.details().c_str()); GPR_ASSERT(s.IsOk()); s = publisher.Publish(topic, kMessageData); - gpr_log(GPR_INFO, "Publish %s returns code %d, %s", - kMessageData, s.code(), s.details().c_str()); + gpr_log(GPR_INFO, "Publish %s returns code %d, %s", kMessageData, s.code(), + s.details().c_str()); GPR_ASSERT(s.IsOk()); grpc::string data; s = subscriber.Pull(subscription_name, &data); gpr_log(GPR_INFO, "Pull %s", data.c_str()); - s = subscriber.DeleteSubscription(subscription_name); - gpr_log(GPR_INFO, "Delete subscription returns code %d, %s", - s.code(), s.details().c_str()); + s = subscriber.DeleteSubscription(subscription_name); + gpr_log(GPR_INFO, "Delete subscription returns code %d, %s", s.code(), + s.details().c_str()); GPR_ASSERT(s.IsOk()); s = publisher.DeleteTopic(topic); - gpr_log(GPR_INFO, "Delete topic returns code %d, %s", - s.code(), s.details().c_str()); + gpr_log(GPR_INFO, "Delete topic returns code %d, %s", s.code(), + s.details().c_str()); GPR_ASSERT(s.IsOk()); subscriber.Shutdown(); diff --git a/examples/pubsub/publisher.cc b/examples/pubsub/publisher.cc index 308f9a77e5..458050af73 100644 --- a/examples/pubsub/publisher.cc +++ b/examples/pubsub/publisher.cc @@ -51,12 +51,9 @@ namespace examples { namespace pubsub { Publisher::Publisher(std::shared_ptr<ChannelInterface> channel) - : stub_(PublisherService::NewStub(channel)) { -} + : stub_(PublisherService::NewStub(channel)) {} -void Publisher::Shutdown() { - stub_.reset(); -} +void Publisher::Shutdown() { stub_.reset(); } Status Publisher::CreateTopic(const grpc::string& topic) { Topic request; diff --git a/examples/pubsub/publisher.h b/examples/pubsub/publisher.h index c90406ffef..33bcf98df4 100644 --- a/examples/pubsub/publisher.h +++ b/examples/pubsub/publisher.h @@ -37,7 +37,7 @@ #include <grpc++/channel_interface.h> #include <grpc++/status.h> -#include "examples/pubsub/pubsub.pb.h" +#include "examples/pubsub/pubsub.grpc.pb.h" namespace grpc { namespace examples { diff --git a/examples/pubsub/publisher_test.cc b/examples/pubsub/publisher_test.cc index 62442c7384..ac4921283f 100644 --- a/examples/pubsub/publisher_test.cc +++ b/examples/pubsub/publisher_test.cc @@ -31,8 +31,6 @@ * */ -#include <google/protobuf/stubs/common.h> - #include <grpc++/channel_arguments.h> #include <grpc++/channel_interface.h> #include <grpc++/client_context.h> @@ -84,20 +82,19 @@ class PublisherServiceImpl : public tech::pubsub::PublisherService::Service { Status ListTopics( ServerContext* context, const ::tech::pubsub::ListTopicsRequest* request, ::tech::pubsub::ListTopicsResponse* response) GRPC_OVERRIDE { - std::ostringstream ss; - ss << "cloud.googleapis.com/project in (/projects/" << kProjectId << ")"; - EXPECT_EQ(request->query(), ss.str()); - response->add_topic()->set_name(kTopic); - return Status::OK; - } - - Status DeleteTopic(ServerContext* context, - const ::tech::pubsub::DeleteTopicRequest* request, - ::proto2::Empty* response) GRPC_OVERRIDE { - EXPECT_EQ(request->topic(), kTopic); + std::ostringstream ss; + ss << "cloud.googleapis.com/project in (/projects/" << kProjectId << ")"; + EXPECT_EQ(request->query(), ss.str()); + response->add_topic()->set_name(kTopic); return Status::OK; - } + } + Status DeleteTopic(ServerContext* context, + const ::tech::pubsub::DeleteTopicRequest* request, + ::proto2::Empty* response) GRPC_OVERRIDE { + EXPECT_EQ(request->topic(), kTopic); + return Status::OK; + } }; class PublisherTest : public ::testing::Test { @@ -107,11 +104,13 @@ class PublisherTest : public ::testing::Test { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), grpc::InsecureServerCredentials()); + builder.AddListeningPort(server_address_.str(), + grpc::InsecureServerCredentials()); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments()); + channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), + ChannelArguments()); publisher_.reset(new grpc::examples::pubsub::Publisher(channel_)); } diff --git a/examples/pubsub/subscriber.cc b/examples/pubsub/subscriber.cc index 29f6635b7c..d9e0292ba0 100644 --- a/examples/pubsub/subscriber.cc +++ b/examples/pubsub/subscriber.cc @@ -49,12 +49,9 @@ namespace examples { namespace pubsub { Subscriber::Subscriber(std::shared_ptr<ChannelInterface> channel) - : stub_(SubscriberService::NewStub(channel)) { -} + : stub_(SubscriberService::NewStub(channel)) {} -void Subscriber::Shutdown() { - stub_.reset(); -} +void Subscriber::Shutdown() { stub_.reset(); } Status Subscriber::CreateSubscription(const grpc::string& topic, const grpc::string& name) { diff --git a/examples/pubsub/subscriber.h b/examples/pubsub/subscriber.h index c587c01b82..40ab45471d 100644 --- a/examples/pubsub/subscriber.h +++ b/examples/pubsub/subscriber.h @@ -37,7 +37,7 @@ #include <grpc++/channel_interface.h> #include <grpc++/status.h> -#include "examples/pubsub/pubsub.pb.h" +#include "examples/pubsub/pubsub.grpc.pb.h" namespace grpc { namespace examples { diff --git a/examples/pubsub/subscriber_test.cc b/examples/pubsub/subscriber_test.cc index b8dd1f9486..9ab60ed6a7 100644 --- a/examples/pubsub/subscriber_test.cc +++ b/examples/pubsub/subscriber_test.cc @@ -31,8 +31,6 @@ * */ -#include <google/protobuf/stubs/common.h> - #include <grpc++/channel_arguments.h> #include <grpc++/channel_interface.h> #include <grpc++/client_context.h> @@ -95,7 +93,6 @@ class SubscriberServiceImpl : public tech::pubsub::SubscriberService::Service { proto2::Empty* response) GRPC_OVERRIDE { return Status::OK; } - }; class SubscriberTest : public ::testing::Test { @@ -105,11 +102,13 @@ class SubscriberTest : public ::testing::Test { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), grpc::InsecureServerCredentials()); + builder.AddListeningPort(server_address_.str(), + grpc::InsecureServerCredentials()); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments()); + channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), + ChannelArguments()); subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_)); } @@ -129,17 +128,15 @@ class SubscriberTest : public ::testing::Test { }; TEST_F(SubscriberTest, TestSubscriber) { - EXPECT_TRUE(subscriber_->CreateSubscription(kTopic, - kSubscriptionName).IsOk()); + EXPECT_TRUE( + subscriber_->CreateSubscription(kTopic, kSubscriptionName).IsOk()); grpc::string topic; - EXPECT_TRUE(subscriber_->GetSubscription(kSubscriptionName, - &topic).IsOk()); + EXPECT_TRUE(subscriber_->GetSubscription(kSubscriptionName, &topic).IsOk()); EXPECT_EQ(topic, kTopic); grpc::string data; - EXPECT_TRUE(subscriber_->Pull(kSubscriptionName, - &data).IsOk()); + EXPECT_TRUE(subscriber_->Pull(kSubscriptionName, &data).IsOk()); EXPECT_TRUE(subscriber_->DeleteSubscription(kSubscriptionName).IsOk()); } diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h index f4619a1060..e6a8c6fe55 100644 --- a/include/grpc++/completion_queue.h +++ b/include/grpc++/completion_queue.h @@ -36,6 +36,7 @@ #include <chrono> #include <grpc++/impl/client_unary_call.h> +#include <grpc/support/time.h> struct grpc_completion_queue; @@ -88,9 +89,7 @@ class CompletionQueue { // Returns false if the queue is ready for destruction, true if event bool Next(void** tag, bool* ok) { - return ( - AsyncNext(tag, ok, (std::chrono::system_clock::time_point::max)()) != - SHUTDOWN); + return (AsyncNextInternal(tag, ok, gpr_inf_future) != SHUTDOWN); } // Shutdown has to be called, and the CompletionQueue can only be @@ -122,6 +121,8 @@ class CompletionQueue { const grpc::protobuf::Message& request, grpc::protobuf::Message* result); + NextStatus AsyncNextInternal(void** tag, bool* ok, gpr_timespec deadline); + // Wraps grpc_completion_queue_pluck. // Cannot be mixed with calls to Next(). bool Pluck(CompletionQueueTag* tag); diff --git a/include/grpc++/config.h b/include/grpc++/config.h index 35bf507364..0f3d69289f 100644 --- a/include/grpc++/config.h +++ b/include/grpc++/config.h @@ -34,11 +34,46 @@ #ifndef GRPCXX_CONFIG_H #define GRPCXX_CONFIG_H -#ifdef GRPC_OLD_CXX +#if !defined(GRPC_NO_AUTODETECT_PLATFORM) + +#ifdef _MSC_VER +// Visual Studio 2010 is 1600. +#if _MSC_VER < 1600 +#error "gRPC is only supported with Visual Studio starting at 2010" +// Visual Studio 2013 is 1800. +#elif _MSC_VER < 1800 +#define GRPC_CXX0X_NO_FINAL 1 +#define GRPC_CXX0X_NO_OVERRIDE 1 +#define GRPC_CXX0X_NO_CHRONO 1 +#define GRPC_CXX0X_NO_THREAD 1 +#endif +#endif // Visual Studio + +#ifndef __clang__ +#ifdef __GNUC__ +// nullptr was added in gcc 4.6 +#if (__GNUC__ * 100 + __GNUC_MINOR__ < 406) +#define GRPC_CXX0X_NO_NULLPTR 1 +#endif +// final and override were added in gcc 4.7 +#if (__GNUC__ * 100 + __GNUC_MINOR__ < 407) +#define GRPC_CXX0X_NO_FINAL 1 +#define GRPC_CXX0X_NO_OVERRIDE 1 +#endif +#endif +#endif + +#endif + +#ifdef GRPC_CXX0X_NO_FINAL #define GRPC_FINAL -#define GRPC_OVERRIDE #else #define GRPC_FINAL final +#endif + +#ifdef GRPC_CXX0X_NO_OVERRIDE +#define GRPC_OVERRIDE +#else #define GRPC_OVERRIDE override #endif @@ -65,6 +100,20 @@ ::google::protobuf::io::ZeroCopyInputStream #endif +#ifdef GRPC_CXX0X_NO_NULLPTR +#include <memory> +const class { +public: + template <class T> operator T*() const {return static_cast<T *>(0);} + template <class T> operator std::unique_ptr<T>() const { + return std::unique_ptr<T>(static_cast<T *>(0)); + } + operator bool() const {return false;} +private: + void operator&() const = delete; +} nullptr = {}; +#endif + namespace grpc { typedef GRPC_CUSTOM_STRING string; diff --git a/include/grpc++/generic_stub.h b/include/grpc++/generic_stub.h index d4c8380ad4..c34e1fcf55 100644 --- a/include/grpc++/generic_stub.h +++ b/include/grpc++/generic_stub.h @@ -39,6 +39,7 @@ namespace grpc { +class CompletionQueue; typedef ClientAsyncReaderWriter<ByteBuffer, ByteBuffer> GenericClientAsyncReaderWriter; @@ -51,7 +52,8 @@ class GenericStub GRPC_FINAL { // begin a call to a named method std::unique_ptr<GenericClientAsyncReaderWriter> Call( - ClientContext* context, const grpc::string& method); + ClientContext* context, const grpc::string& method, + CompletionQueue* cq, void* tag); private: std::shared_ptr<ChannelInterface> channel_; diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h index e117ac6313..b14c41dfa6 100644 --- a/include/grpc++/impl/call.h +++ b/include/grpc++/impl/call.h @@ -109,7 +109,9 @@ class CallOpBuffer : public CompletionQueueTag { char* status_details_; size_t status_details_capacity_; // Server send status - const Status* send_status_; + bool send_status_available_; + grpc_status_code send_status_code_; + grpc::string send_status_details_; size_t trailing_metadata_count_; grpc_metadata* trailing_metadata_; int cancelled_buf_; diff --git a/src/php/ext/grpc/event.h b/include/grpc++/impl/sync.h index ef5846aee1..2f41d2bdeb 100755..100644 --- a/src/php/ext/grpc/event.h +++ b/include/grpc++/impl/sync.h @@ -31,21 +31,15 @@ * */ -#ifndef NET_GRPC_PHP_GRPC_EVENT_H_ -#define NET_GRPC_PHP_GRPC_EVENT_H_ +#ifndef GRPCXX_IMPL_SYNC_H +#define GRPCXX_IMPL_SYNC_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_grpc.h" +#include <grpc++/config.h> -#include "grpc/grpc.h" - -/* Create a new Event object that wraps an existing grpc_event struct */ -zval *grpc_php_convert_event(grpc_event *event); +#ifdef GRPC_CXX0X_NO_THREAD +#include <grpc++/impl/sync_no_cxx11.h> +#else +#include <grpc++/impl/sync_cxx11.h> +#endif -#endif /* NET_GRPC_PHP_GRPC_COMPLETION_CHANNEL_H */ +#endif // GRPCXX_IMPL_SYNC_H diff --git a/src/php/lib/autoload.php b/include/grpc++/impl/sync_cxx11.h index 42eb33d65b..4e6f1da3a6 100755..100644 --- a/src/php/lib/autoload.php +++ b/include/grpc++/impl/sync_cxx11.h @@ -1,4 +1,3 @@ -<?php /* * * Copyright 2015, Google Inc. @@ -31,23 +30,20 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -function grpcAutoloader($class) { - $prefix = 'Grpc\\'; - $base_dir = __DIR__ . '/Grpc/'; +#ifndef GRPCXX_IMPL_SYNC_CXX11_H +#define GRPCXX_IMPL_SYNC_CXX11_H - $len = strlen($prefix); - if (strncmp($prefix, $class, $len) !== 0) { - return; - } +#include <condition_variable> +#include <mutex> - $relative_class = substr($class, $len); +namespace grpc { - $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; +using std::condition_variable; +using std::mutex; +using std::lock_guard; +using std::unique_lock; - if (file_exists($file)) { - include $file; - } -} +} // namespace grpc -spl_autoload_register('grpcAutoloader'); +#endif // GRPCXX_IMPL_SYNC_CXX11_H diff --git a/include/grpc++/impl/sync_no_cxx11.h b/include/grpc++/impl/sync_no_cxx11.h new file mode 100644 index 0000000000..5636373b81 --- /dev/null +++ b/include/grpc++/impl/sync_no_cxx11.h @@ -0,0 +1,101 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_SYNC_NO_CXX11_H +#define GRPCXX_IMPL_SYNC_NO_CXX11_H + +#include <grpc/support/sync.h> + +namespace grpc { + +template<class mutex> +class lock_guard; +class condition_variable; + +class mutex { + public: + mutex() { gpr_mu_init(&mu_); } + ~mutex() { gpr_mu_destroy(&mu_); } + private: + ::gpr_mu mu_; + template <class mutex> + friend class lock_guard; + friend class condition_variable; +}; + +template <class mutex> +class lock_guard { + public: + lock_guard(mutex &mu) : mu_(mu), locked(true) { gpr_mu_lock(&mu.mu_); } + ~lock_guard() { unlock_internal(); } + protected: + void lock_internal() { + if (!locked) gpr_mu_lock(&mu_.mu_); + locked = true; + } + void unlock_internal() { + if (locked) gpr_mu_unlock(&mu_.mu_); + locked = false; + } + private: + mutex &mu_; + bool locked; + friend class condition_variable; +}; + +template <class mutex> +class unique_lock : public lock_guard<mutex> { + public: + unique_lock(mutex &mu) : lock_guard(mu) { } + void lock() { lock_internal(); } + void unlock() { unlock_internal(); } +}; + +class condition_variable { + public: + condition_variable() { gpr_cv_init(&cv_); } + ~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); + mu.locked = true; + } + void notify_one() { gpr_cv_signal(&cv_); } + void notify_all() { gpr_cv_broadcast(&cv_); } + private: + gpr_cv cv_; +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_SYNC_NO_CXX11_H diff --git a/src/php/tests/unit_tests/CompletionQueueTest.php b/include/grpc++/impl/thd.h index 76ee61dfe8..4c4578a92d 100755..100644 --- a/src/php/tests/unit_tests/CompletionQueueTest.php +++ b/include/grpc++/impl/thd.h @@ -1,4 +1,3 @@ -<?php /* * * Copyright 2015, Google Inc. @@ -31,16 +30,16 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -class CompletionQueueTest extends PHPUnit_Framework_TestCase{ - public function testNextReturnsNullWithNoCall() { - $cq = new Grpc\CompletionQueue(); - $event = $cq->next(Grpc\Timeval::zero()); - $this->assertNull($event); - } - public function testPluckReturnsNullWithNoCall() { - $cq = new Grpc\CompletionQueue(); - $event = $cq->pluck(0, Grpc\Timeval::zero()); - $this->assertNull($event); - } -} +#ifndef GRPCXX_IMPL_THD_H +#define GRPCXX_IMPL_THD_H + +#include <grpc++/config.h> + +#ifdef GRPC_CXX0X_NO_THREAD +#include <grpc++/impl/thd_no_cxx11.h> +#else +#include <grpc++/impl/thd_cxx11.h> +#endif + +#endif // GRPCXX_IMPL_THD_H diff --git a/include/grpc++/impl/thd_cxx11.h b/include/grpc++/impl/thd_cxx11.h new file mode 100644 index 0000000000..2055b1d538 --- /dev/null +++ b/include/grpc++/impl/thd_cxx11.h @@ -0,0 +1,45 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_THD_CXX11_H +#define GRPCXX_IMPL_THD_CXX11_H + +#include <thread> + +namespace grpc { + +using std::thread; + +} // namespace grpc + +#endif // GRPCXX_IMPL_THD_CXX11_H diff --git a/include/grpc++/impl/thd_no_cxx11.h b/include/grpc++/impl/thd_no_cxx11.h new file mode 100644 index 0000000000..a01b931df8 --- /dev/null +++ b/include/grpc++/impl/thd_no_cxx11.h @@ -0,0 +1,89 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_THD_NO_CXX11_H +#define GRPCXX_IMPL_THD_NO_CXX11_H + +#include <grpc/support/thd.h> + +namespace grpc { + +class thread { + public: + template<class T> thread(void (T::*fptr)(), T *obj) { + func_ = new thread_function<T>(fptr, obj); + joined_ = false; + start(); + } + ~thread() { + if (!joined_) std::terminate(); + delete func_; + } + void join() { + gpr_thd_join(thd_); + joined_ = true; + } + private: + void start() { + gpr_thd_options options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&options); + gpr_thd_new(&thd_, thread_func, (void *) func_, &options); + } + static void thread_func(void *arg) { + thread_function_base *func = (thread_function_base *) arg; + func->call(); + } + class thread_function_base { + public: + virtual ~thread_function_base() { } + virtual void call() = 0; + }; + template<class T> + class thread_function : public thread_function_base { + public: + thread_function(void (T::*fptr)(), T *obj) + : fptr_(fptr) + , obj_(obj) { } + virtual void call() { (obj_->*fptr_)(); } + private: + void (T::*fptr_)(); + T *obj_; + }; + thread_function_base *func_; + gpr_thd_id thd_; + bool joined_; +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_THD_NO_CXX11_H diff --git a/include/grpc++/server.h b/include/grpc++/server.h index bddb4f62aa..eb50611573 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -34,15 +34,14 @@ #ifndef GRPCXX_SERVER_H #define GRPCXX_SERVER_H -#include <condition_variable> #include <list> #include <memory> -#include <mutex> #include <grpc++/completion_queue.h> #include <grpc++/config.h> #include <grpc++/impl/call.h> #include <grpc++/impl/service_type.h> +#include <grpc++/impl/sync.h> #include <grpc++/status.h> struct grpc_server; @@ -110,12 +109,12 @@ class Server GRPC_FINAL : private CallHook, CompletionQueue cq_; // Sever status - std::mutex mu_; + grpc::mutex mu_; bool started_; bool shutdown_; // The number of threads which are running callbacks. int num_running_cb_; - std::condition_variable callback_cv_; + grpc::condition_variable callback_cv_; std::list<SyncRequest> sync_methods_; diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h index 53f6cd098f..034de5bd34 100644 --- a/include/grpc/support/port_platform.h +++ b/include/grpc/support/port_platform.h @@ -223,7 +223,7 @@ #endif #if defined(GPR_POSIX_SOCKET) + defined(GPR_WIN32) != 1 -#error Must define exactly one of GPR_POSIX_POLLSET, GPR_WIN32 +#error Must define exactly one of GPR_POSIX_SOCKET, GPR_WIN32 #endif typedef int16_t gpr_int16; diff --git a/include/grpc/support/thd.h b/include/grpc/support/thd.h index 64d5bed49a..8126992d6b 100644 --- a/include/grpc/support/thd.h +++ b/include/grpc/support/thd.h @@ -52,9 +52,8 @@ typedef gpr_uint64 gpr_thd_id; /* Thread creation options. */ typedef struct { - int flags; /* Flags below can be set here. Default value 0. */ + int flags; /* Opaque field. Get and set with accessors below. */ } gpr_thd_options; -/* No flags are currently defined. */ /* Create a new thread running (*thd_body)(arg) and place its thread identifier in *t, and return true. If there are insufficient resources, return false. @@ -66,9 +65,25 @@ int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, /* Return a gpr_thd_options struct with all fields set to defaults. */ gpr_thd_options gpr_thd_options_default(void); +/* Set the thread to become detached on startup - this is the default. */ +void gpr_thd_options_set_detached(gpr_thd_options *options); + +/* Set the thread to become joinable - mutually exclusive with detached. */ +void gpr_thd_options_set_joinable(gpr_thd_options *options); + +/* Returns non-zero if the option detached is set. */ +int gpr_thd_options_is_detached(const gpr_thd_options *options); + +/* Returns non-zero if the option joinable is set. */ +int gpr_thd_options_is_joinable(const gpr_thd_options *options); + /* Returns the identifier of the current thread. */ gpr_thd_id gpr_thd_currentid(void); +/* Blocks until the specified thread properly terminates. + Calling this on a detached thread has unpredictable results. */ +void gpr_thd_join(gpr_thd_id t); + #ifdef __cplusplus } #endif diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index d5004624d4..c78f0333d8 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -109,9 +109,49 @@ bool HasBidiStreaming(const grpc::protobuf::FileDescriptor *file) { } return false; } + +grpc::string FilenameIdentifier(const grpc::string& filename) { + grpc::string result; + for (unsigned i = 0; i < filename.size(); i++) { + char c = filename[i]; + if (isalnum(c)) { + result.push_back(c); + } else { + static char hex[] = "0123456789abcdef"; + result.push_back('_'); + result.push_back(hex[(c >> 4) & 0xf]); + result.push_back(hex[c & 0xf]); + } + } + return result; +} } // namespace -grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file) { +grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + vars["filename"] = file->name(); + vars["filename_identifier"] = FilenameIdentifier(file->name()); + vars["filename_base"] = grpc_generator::StripProto(file->name()); + + printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n"); + printer.Print(vars, "// If you make any local change, they will be lost.\n"); + printer.Print(vars, "// source: $filename$\n"); + printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n"); + printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n"); + printer.Print(vars, "\n"); + printer.Print(vars, "#include \"$filename_base$.pb.h\"\n"); + printer.Print(vars, "\n"); + + return output; +} + +grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { grpc::string temp = "#include <grpc++/impl/internal_stub.h>\n" "#include <grpc++/impl/service_type.h>\n" @@ -155,17 +195,21 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file) { "class ServerAsyncReaderWriter;\n"); } temp.append("} // namespace grpc\n"); - return temp; -} -grpc::string GetSourceIncludes() { - return "#include <grpc++/async_unary_call.h>\n" - "#include <grpc++/channel_interface.h>\n" - "#include <grpc++/impl/client_unary_call.h>\n" - "#include <grpc++/impl/rpc_method.h>\n" - "#include <grpc++/impl/rpc_service_method.h>\n" - "#include <grpc++/impl/service_type.h>\n" - "#include <grpc++/stream.h>\n"; + temp.append("\n"); + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.begin(); part != parts.end(); part++) { + temp.append("namespace "); + temp.append(*part); + temp.append(" {\n"); + } + + temp.append("\n"); + + return temp; } void PrintHeaderClientMethod(grpc::protobuf::io::Printer *printer, @@ -353,16 +397,99 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer, printer->Print("};\n"); } -grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file) { +grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { grpc::string output; grpc::protobuf::io::StringOutputStream output_stream(&output); grpc::protobuf::io::Printer printer(&output_stream, '$'); std::map<grpc::string, grpc::string> vars; + if (!params.services_namespace.empty()) { + vars["services_namespace"] = params.services_namespace; + printer.Print(vars, "\nnamespace $services_namespace$ {\n\n"); + } + for (int i = 0; i < file->service_count(); ++i) { PrintHeaderService(&printer, file->service(i), &vars); printer.Print("\n"); } + + if (!params.services_namespace.empty()) { + printer.Print(vars, "} // namespace $services_namespace$\n\n"); + } + + return output; +} + +grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + vars["filename"] = file->name(); + vars["filename_identifier"] = FilenameIdentifier(file->name()); + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.rbegin(); part != parts.rend(); part++) { + vars["part"] = *part; + printer.Print(vars, "} // namespace $part$\n"); + } + + printer.Print(vars, "\n\n"); + printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n"); + + return output; +} + +grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + vars["filename"] = file->name(); + vars["filename_base"] = grpc_generator::StripProto(file->name()); + + printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n"); + printer.Print(vars, "// If you make any local change, they will be lost.\n"); + printer.Print(vars, "// source: $filename$\n\n"); + printer.Print(vars, "#include \"$filename_base$.pb.h\"\n"); + printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n"); + printer.Print(vars, "\n"); + + return output; +} + +grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶m) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + + printer.Print(vars, "#include <grpc++/async_unary_call.h>\n"); + printer.Print(vars, "#include <grpc++/channel_interface.h>\n"); + printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n"); + printer.Print(vars, "#include <grpc++/impl/rpc_method.h>\n"); + printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n"); + printer.Print(vars, "#include <grpc++/impl/service_type.h>\n"); + printer.Print(vars, "#include <grpc++/stream.h>\n"); + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.begin(); part != parts.end(); part++) { + vars["part"] = *part; + printer.Print(vars, "namespace $part$ {\n"); + } + + printer.Print(vars, "\n"); + return output; } @@ -376,18 +503,18 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer, grpc_cpp_generator::ClassName(method->output_type(), true); if (NoStreaming(method)) { printer->Print(*vars, - "::grpc::Status $Service$::Stub::$Method$(" + "::grpc::Status $ns$$Service$::Stub::$Method$(" "::grpc::ClientContext* context, " "const $Request$& request, $Response$* response) {\n"); printer->Print(*vars, " return ::grpc::BlockingUnaryCall(channel()," - "::grpc::RpcMethod($Service$_method_names[$Idx$]), " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), " "context, request, response);\n" "}\n\n"); printer->Print( *vars, "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> " - "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, " + "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, " "const $Request$& request, " "::grpc::CompletionQueue* cq, void* tag) {\n"); printer->Print(*vars, @@ -395,32 +522,32 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer, "::grpc::ClientAsyncResponseReader< $Response$>>(new " "::grpc::ClientAsyncResponseReader< $Response$>(" "channel(), cq, " - "::grpc::RpcMethod($Service$_method_names[$Idx$]), " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), " "context, request, tag));\n" "}\n\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, "std::unique_ptr< ::grpc::ClientWriter< $Request$>> " - "$Service$::Stub::$Method$(" + "$ns$$Service$::Stub::$Method$(" "::grpc::ClientContext* context, $Response$* response) {\n"); printer->Print(*vars, " return std::unique_ptr< ::grpc::ClientWriter< " "$Request$>>(new ::grpc::ClientWriter< $Request$>(" "channel()," - "::grpc::RpcMethod($Service$_method_names[$Idx$], " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], " "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), " "context, response));\n" "}\n\n"); printer->Print(*vars, "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> " - "$Service$::Stub::Async$Method$(" + "$ns$$Service$::Stub::Async$Method$(" "::grpc::ClientContext* context, $Response$* response, " "::grpc::CompletionQueue* cq, void* tag) {\n"); printer->Print(*vars, " return std::unique_ptr< ::grpc::ClientAsyncWriter< " "$Request$>>(new ::grpc::ClientAsyncWriter< $Request$>(" "channel(), cq, " - "::grpc::RpcMethod($Service$_method_names[$Idx$], " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], " "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), " "context, response, tag));\n" "}\n\n"); @@ -428,26 +555,26 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer, printer->Print( *vars, "std::unique_ptr< ::grpc::ClientReader< $Response$>> " - "$Service$::Stub::$Method$(" + "$ns$$Service$::Stub::$Method$(" "::grpc::ClientContext* context, const $Request$& request) {\n"); printer->Print(*vars, " return std::unique_ptr< ::grpc::ClientReader< " "$Response$>>(new ::grpc::ClientReader< $Response$>(" "channel()," - "::grpc::RpcMethod($Service$_method_names[$Idx$], " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], " "::grpc::RpcMethod::RpcType::SERVER_STREAMING), " "context, request));\n" "}\n\n"); printer->Print(*vars, "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> " - "$Service$::Stub::Async$Method$(" + "$ns$$Service$::Stub::Async$Method$(" "::grpc::ClientContext* context, const $Request$& request, " "::grpc::CompletionQueue* cq, void* tag) {\n"); printer->Print(*vars, " return std::unique_ptr< ::grpc::ClientAsyncReader< " "$Response$>>(new ::grpc::ClientAsyncReader< $Response$>(" "channel(), cq, " - "::grpc::RpcMethod($Service$_method_names[$Idx$], " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], " "::grpc::RpcMethod::RpcType::SERVER_STREAMING), " "context, request, tag));\n" "}\n\n"); @@ -455,27 +582,27 @@ void PrintSourceClientMethod(grpc::protobuf::io::Printer *printer, printer->Print( *vars, "std::unique_ptr< ::grpc::ClientReaderWriter< $Request$, $Response$>> " - "$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n"); + "$ns$$Service$::Stub::$Method$(::grpc::ClientContext* context) {\n"); printer->Print(*vars, " return std::unique_ptr< ::grpc::ClientReaderWriter< " "$Request$, $Response$>>(new ::grpc::ClientReaderWriter< " "$Request$, $Response$>(" "channel()," - "::grpc::RpcMethod($Service$_method_names[$Idx$], " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], " "::grpc::RpcMethod::RpcType::BIDI_STREAMING), " "context));\n" "}\n\n"); printer->Print(*vars, "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< " "$Request$, $Response$>> " - "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, " + "$ns$$Service$::Stub::Async$Method$(::grpc::ClientContext* context, " "::grpc::CompletionQueue* cq, void* tag) {\n"); printer->Print(*vars, " return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< " "$Request$, $Response$>>(new " "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>(" "channel(), cq, " - "::grpc::RpcMethod($Service$_method_names[$Idx$], " + "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], " "::grpc::RpcMethod::RpcType::BIDI_STREAMING), " "context, tag));\n" "}\n\n"); @@ -492,7 +619,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer, grpc_cpp_generator::ClassName(method->output_type(), true); if (NoStreaming(method)) { printer->Print(*vars, - "::grpc::Status $Service$::Service::$Method$(" + "::grpc::Status $ns$$Service$::Service::$Method$(" "::grpc::ServerContext* context, " "const $Request$* request, $Response$* response) {\n"); printer->Print( @@ -501,7 +628,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer, printer->Print("}\n\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, - "::grpc::Status $Service$::Service::$Method$(" + "::grpc::Status $ns$$Service$::Service::$Method$(" "::grpc::ServerContext* context, " "::grpc::ServerReader< $Request$>* reader, " "$Response$* response) {\n"); @@ -511,7 +638,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer, printer->Print("}\n\n"); } else if (ServerOnlyStreaming(method)) { printer->Print(*vars, - "::grpc::Status $Service$::Service::$Method$(" + "::grpc::Status $ns$$Service$::Service::$Method$(" "::grpc::ServerContext* context, " "const $Request$* request, " "::grpc::ServerWriter< $Response$>* writer) {\n"); @@ -521,7 +648,7 @@ void PrintSourceServerMethod(grpc::protobuf::io::Printer *printer, printer->Print("}\n\n"); } else if (BidiStreaming(method)) { printer->Print(*vars, - "::grpc::Status $Service$::Service::$Method$(" + "::grpc::Status $ns$$Service$::Service::$Method$(" "::grpc::ServerContext* context, " "::grpc::ServerReaderWriter< $Response$, $Request$>* " "stream) {\n"); @@ -543,7 +670,7 @@ void PrintSourceServerAsyncMethod( grpc_cpp_generator::ClassName(method->output_type(), true); if (NoStreaming(method)) { printer->Print(*vars, - "void $Service$::AsyncService::Request$Method$(" + "void $ns$$Service$::AsyncService::Request$Method$(" "::grpc::ServerContext* context, " "$Request$* request, " "::grpc::ServerAsyncResponseWriter< $Response$>* response, " @@ -554,7 +681,7 @@ void PrintSourceServerAsyncMethod( printer->Print("}\n\n"); } else if (ClientOnlyStreaming(method)) { printer->Print(*vars, - "void $Service$::AsyncService::Request$Method$(" + "void $ns$$Service$::AsyncService::Request$Method$(" "::grpc::ServerContext* context, " "::grpc::ServerAsyncReader< $Response$, $Request$>* reader, " "::grpc::CompletionQueue* cq, void* tag) {\n"); @@ -564,7 +691,7 @@ void PrintSourceServerAsyncMethod( printer->Print("}\n\n"); } else if (ServerOnlyStreaming(method)) { printer->Print(*vars, - "void $Service$::AsyncService::Request$Method$(" + "void $ns$$Service$::AsyncService::Request$Method$(" "::grpc::ServerContext* context, " "$Request$* request, " "::grpc::ServerAsyncWriter< $Response$>* writer, " @@ -576,7 +703,7 @@ void PrintSourceServerAsyncMethod( } else if (BidiStreaming(method)) { printer->Print( *vars, - "void $Service$::AsyncService::Request$Method$(" + "void $ns$$Service$::AsyncService::Request$Method$(" "::grpc::ServerContext* context, " "::grpc::ServerAsyncReaderWriter< $Response$, $Request$>* stream, " "::grpc::CompletionQueue* cq, void *tag) {\n"); @@ -592,7 +719,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer, std::map<grpc::string, grpc::string> *vars) { (*vars)["Service"] = service->name(); - printer->Print(*vars, "static const char* $Service$_method_names[] = {\n"); + printer->Print(*vars, "static const char* $prefix$$Service$_method_names[] = {\n"); for (int i = 0; i < service->method_count(); ++i) { (*vars)["Method"] = service->method(i)->name(); printer->Print(*vars, " \"/$Package$$Service$/$Method$\",\n"); @@ -601,9 +728,9 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer, printer->Print( *vars, - "std::unique_ptr< $Service$::Stub> $Service$::NewStub(" + "std::unique_ptr< $ns$$Service$::Stub> $ns$$Service$::NewStub(" "const std::shared_ptr< ::grpc::ChannelInterface>& channel) {\n" - " std::unique_ptr< $Service$::Stub> stub(new $Service$::Stub());\n" + " std::unique_ptr< $ns$$Service$::Stub> stub(new $ns$$Service$::Stub());\n" " stub->set_channel(channel);\n" " return stub;\n" "}\n\n"); @@ -615,12 +742,12 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer, (*vars)["MethodCount"] = as_string(service->method_count()); printer->Print( *vars, - "$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : " - "::grpc::AsynchronousService(cq, $Service$_method_names, $MethodCount$) " + "$ns$$Service$::AsyncService::AsyncService(::grpc::CompletionQueue* cq) : " + "::grpc::AsynchronousService(cq, $prefix$$Service$_method_names, $MethodCount$) " "{}\n\n"); printer->Print(*vars, - "$Service$::Service::~Service() {\n" + "$ns$$Service$::Service::~Service() {\n" " delete service_;\n" "}\n\n"); for (int i = 0; i < service->method_count(); ++i) { @@ -629,7 +756,7 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer, PrintSourceServerAsyncMethod(printer, service->method(i), vars); } printer->Print(*vars, - "::grpc::RpcService* $Service$::Service::service() {\n"); + "::grpc::RpcService* $ns$$Service$::Service::service() {\n"); printer->Indent(); printer->Print( "if (service_ != nullptr) {\n" @@ -648,52 +775,52 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer, printer->Print( *vars, "service_->AddMethod(new ::grpc::RpcServiceMethod(\n" - " $Service$_method_names[$Idx$],\n" + " $prefix$$Service$_method_names[$Idx$],\n" " ::grpc::RpcMethod::NORMAL_RPC,\n" - " new ::grpc::RpcMethodHandler< $Service$::Service, $Request$, " + " new ::grpc::RpcMethodHandler< $ns$$Service$::Service, $Request$, " "$Response$>(\n" - " std::function< ::grpc::Status($Service$::Service*, " + " std::function< ::grpc::Status($ns$$Service$::Service*, " "::grpc::ServerContext*, const $Request$*, $Response$*)>(" - "&$Service$::Service::$Method$), this),\n" + "&$ns$$Service$::Service::$Method$), this),\n" " new $Request$, new $Response$));\n"); } else if (ClientOnlyStreaming(method)) { printer->Print( *vars, "service_->AddMethod(new ::grpc::RpcServiceMethod(\n" - " $Service$_method_names[$Idx$],\n" + " $prefix$$Service$_method_names[$Idx$],\n" " ::grpc::RpcMethod::CLIENT_STREAMING,\n" " new ::grpc::ClientStreamingHandler< " - "$Service$::Service, $Request$, $Response$>(\n" - " std::function< ::grpc::Status($Service$::Service*, " + "$ns$$Service$::Service, $Request$, $Response$>(\n" + " std::function< ::grpc::Status($ns$$Service$::Service*, " "::grpc::ServerContext*, " "::grpc::ServerReader< $Request$>*, $Response$*)>(" - "&$Service$::Service::$Method$), this),\n" + "&$ns$$Service$::Service::$Method$), this),\n" " new $Request$, new $Response$));\n"); } else if (ServerOnlyStreaming(method)) { printer->Print( *vars, "service_->AddMethod(new ::grpc::RpcServiceMethod(\n" - " $Service$_method_names[$Idx$],\n" + " $prefix$$Service$_method_names[$Idx$],\n" " ::grpc::RpcMethod::SERVER_STREAMING,\n" " new ::grpc::ServerStreamingHandler< " - "$Service$::Service, $Request$, $Response$>(\n" - " std::function< ::grpc::Status($Service$::Service*, " + "$ns$$Service$::Service, $Request$, $Response$>(\n" + " std::function< ::grpc::Status($ns$$Service$::Service*, " "::grpc::ServerContext*, " "const $Request$*, ::grpc::ServerWriter< $Response$>*)>(" - "&$Service$::Service::$Method$), this),\n" + "&$ns$$Service$::Service::$Method$), this),\n" " new $Request$, new $Response$));\n"); } else if (BidiStreaming(method)) { printer->Print( *vars, "service_->AddMethod(new ::grpc::RpcServiceMethod(\n" - " $Service$_method_names[$Idx$],\n" + " $prefix$$Service$_method_names[$Idx$],\n" " ::grpc::RpcMethod::BIDI_STREAMING,\n" " new ::grpc::BidiStreamingHandler< " - "$Service$::Service, $Request$, $Response$>(\n" - " std::function< ::grpc::Status($Service$::Service*, " + "$ns$$Service$::Service, $Request$, $Response$>(\n" + " std::function< ::grpc::Status($ns$$Service$::Service*, " "::grpc::ServerContext*, " "::grpc::ServerReaderWriter< $Response$, $Request$>*)>(" - "&$Service$::Service::$Method$), this),\n" + "&$ns$$Service$::Service::$Method$), this),\n" " new $Request$, new $Response$));\n"); } } @@ -702,7 +829,8 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer, printer->Print("}\n\n"); } -grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) { +grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { grpc::string output; grpc::protobuf::io::StringOutputStream output_stream(&output); grpc::protobuf::io::Printer printer(&output_stream, '$'); @@ -713,6 +841,13 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) { if (!file->package().empty()) { vars["Package"].append("."); } + if (!params.services_namespace.empty()) { + vars["ns"] = params.services_namespace + "::"; + vars["prefix"] = params.services_namespace; + } else { + vars["ns"] = ""; + vars["prefix"] = ""; + } for (int i = 0; i < file->service_count(); ++i) { PrintSourceService(&printer, file->service(i), &vars); @@ -721,4 +856,22 @@ grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file) { return output; } +grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms) { + grpc::string temp; + + std::vector<grpc::string> parts = + grpc_generator::tokenize(file->package(), "."); + + for (auto part = parts.begin(); part != parts.end(); part++) { + temp.append("} // namespace "); + temp.append(*part); + temp.append("\n"); + } + + temp.append("\n"); + + return temp; +} + } // namespace grpc_cpp_generator diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h index 2ecdb5c47e..70c2e985f6 100644 --- a/src/compiler/cpp_generator.h +++ b/src/compiler/cpp_generator.h @@ -38,17 +38,43 @@ namespace grpc_cpp_generator { +// Contains all the parameters that are parsed from the command line. +struct Parameters { + // Puts the service into a namespace + grpc::string services_namespace; +}; + +// Return the prologue of the generated header file. +grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + // Return the includes needed for generated header file. -grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file); +grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); // Return the includes needed for generated source file. -grpc::string GetSourceIncludes(); +grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + +// Return the epilogue of the generated header file. +grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + +// Return the prologue of the generated source file. +grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); // Return the services for generated header file. -grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file); +grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); // Return the services for generated source file. -grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file); +grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); + +// Return the epilogue of the generated source file. +grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file, + const Parameters ¶ms); } // namespace grpc_cpp_generator diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc index 5b83aa85cf..88c704948e 100644 --- a/src/compiler/cpp_plugin.cc +++ b/src/compiler/cpp_plugin.cc @@ -58,18 +58,48 @@ class CppGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { return false; } + grpc_cpp_generator::Parameters generator_parameters; + + if (!parameter.empty()) { + std::vector<grpc::string> parameters_list = + grpc_generator::tokenize(parameter, ","); + for (auto parameter_string = parameters_list.begin(); + parameter_string != parameters_list.end(); + parameter_string++) { + std::vector<grpc::string> param = + grpc_generator::tokenize(*parameter_string, "="); + if (param[0] == "services_namespace") { + generator_parameters.services_namespace = param[1]; + } else { + *error = grpc::string("Unknown parameter: ") + *parameter_string; + return false; + } + } + } + grpc::string file_name = grpc_generator::StripProto(file->name()); - // Generate .pb.h - Insert(context, file_name + ".pb.h", "includes", - grpc_cpp_generator::GetHeaderIncludes(file)); - Insert(context, file_name + ".pb.h", "namespace_scope", - grpc_cpp_generator::GetHeaderServices(file)); - // Generate .pb.cc - Insert(context, file_name + ".pb.cc", "includes", - grpc_cpp_generator::GetSourceIncludes()); - Insert(context, file_name + ".pb.cc", "namespace_scope", - grpc_cpp_generator::GetSourceServices(file)); + grpc::string header_code = + grpc_cpp_generator::GetHeaderPrologue(file, generator_parameters) + + grpc_cpp_generator::GetHeaderIncludes(file, generator_parameters) + + grpc_cpp_generator::GetHeaderServices(file, generator_parameters) + + grpc_cpp_generator::GetHeaderEpilogue(file, generator_parameters); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output( + context->Open(file_name + ".grpc.pb.h")); + grpc::protobuf::io::CodedOutputStream header_coded_out( + header_output.get()); + header_coded_out.WriteRaw(header_code.data(), header_code.size()); + + grpc::string source_code = + grpc_cpp_generator::GetSourcePrologue(file, generator_parameters) + + grpc_cpp_generator::GetSourceIncludes(file, generator_parameters) + + grpc_cpp_generator::GetSourceServices(file, generator_parameters) + + grpc_cpp_generator::GetSourceEpilogue(file, generator_parameters); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output( + context->Open(file_name + ".grpc.pb.cc")); + grpc::protobuf::io::CodedOutputStream source_coded_out( + source_output.get()); + source_coded_out.WriteRaw(source_code.data(), source_code.size()); return true; } diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h index 1e6727dd4c..374e1374cf 100644 --- a/src/compiler/generator_helpers.h +++ b/src/compiler/generator_helpers.h @@ -75,6 +75,47 @@ inline grpc::string StringReplace(grpc::string str, const grpc::string &from, return str; } +inline std::vector<grpc::string> tokenize(const grpc::string &input, + const grpc::string &delimiters) { + std::vector<grpc::string> tokens; + size_t pos, last_pos = 0; + + for (;;) { + bool done = false; + pos = input.find_first_of(delimiters, last_pos); + if (pos == grpc::string::npos) { + done = true; + pos = input.length(); + } + + tokens.push_back(input.substr(last_pos, pos - last_pos)); + if (done) return tokens; + + last_pos = pos + 1; + } +} + +inline grpc::string CapitalizeFirstLetter(grpc::string s) { + if (s.empty()) { + return s; + } + s[0] = ::toupper(s[0]); + return s; +} + +inline grpc::string LowerUnderscoreToUpperCamel(grpc::string str) { + std::vector<grpc::string> tokens = tokenize(str, "_"); + grpc::string result = ""; + for (unsigned int i = 0; i < tokens.size(); i++) { + result += CapitalizeFirstLetter(tokens[i]); + } + return result; +} + +inline grpc::string FileNameInUpperCamel(const grpc::protobuf::FileDescriptor *file) { + return LowerUnderscoreToUpperCamel(StripProto(file->name())); +} + } // namespace grpc_generator #endif // GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc new file mode 100644 index 0000000000..c68c9c37c2 --- /dev/null +++ b/src/compiler/objective_c_generator.cc @@ -0,0 +1,236 @@ +/* + * + * 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 <map> + +#include "src/compiler/objective_c_generator.h" +#include "src/compiler/objective_c_generator_helpers.h" + +#include "src/compiler/config.h" + +#include <sstream> + +namespace grpc_objective_c_generator { +namespace { + +void PrintSimpleBlockSignature(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + (*vars)["request_type"] = PrefixedName(method->input_type()->name()); + (*vars)["response_type"] = PrefixedName(method->output_type()->name()); + + if (method->server_streaming()) { + printer->Print("// When the response stream finishes, the handler is " + "called with nil for both arguments.\n\n"); + } else { + printer->Print("// The handler is only called once.\n\n"); + } + printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:" + "($request_type$)request completionHandler:(void(^)" + "($response_type$ *, NSError *))handler"); +} + +void PrintSimpleDelegateSignature(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + (*vars)["request_type"] = PrefixedName(method->input_type()->name()); + + printer->Print(*vars, "- (id<GRXLiveSource>)$method_name$WithRequest:" + "($request_type$)request delegate:(id<GRXSink>)delegate"); +} + +void PrintAdvancedSignature(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:" + "(id<GRXSource>)request"); +} + +void PrintSourceMethodSimpleBlock(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + PrintSimpleBlockSignature(printer, method, vars); + + (*vars)["method_name"] = method->name(); + printer->Print(" {\n"); + printer->Indent(); + printer->Print(*vars, "return [[self $method_name$WithRequest:request] " + "connectHandler:^(id value, NSError *error) {\n"); + printer->Indent(); + printer->Print("handler(value, error);\n"); + printer->Outdent(); + printer->Print("}];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void PrintSourceMethodSimpleDelegate(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + PrintSimpleDelegateSignature(printer, method, vars); + + (*vars)["method_name"] = method->name(); + printer->Print(" {\n"); + printer->Indent(); + printer->Print(*vars, "return [[self $method_name$WithRequest:request]" + "connectToSink:delegate];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void PrintSourceMethodAdvanced(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + PrintAdvancedSignature(printer, method, vars); + + (*vars)["method_name"] = method->name(); + printer->Print(" {\n"); + printer->Indent(); + printer->Print(*vars, "return [self $method_name$WithRequest:request " + "client:[self newClient]];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +void PrintSourceMethodHandler(grpc::protobuf::io::Printer *printer, + const grpc::protobuf::MethodDescriptor *method, + std::map<grpc::string, grpc::string> *vars) { + (*vars)["method_name"] = method->name(); + (*vars)["response_type"] = PrefixedName(method->output_type()->name()); + (*vars)["caps_name"] = grpc_generator::CapitalizeFirstLetter(method->name()); + + printer->Print(*vars, "- (GRXSource *)$method_name$WithRequest:" + "(id<GRXSource>)request client:(PBgRPCClient *)client {\n"); + printer->Indent(); + printer->Print(*vars, + "return [self responseWithMethod:$@\"$caps_name\"\n"); + printer->Print(*vars, + " class:[$response_type$ class]\n"); + printer->Print(" request:request\n"); + printer->Print(" client:client];\n"); + printer->Outdent(); + printer->Print("}\n"); +} + +} + +grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, + const grpc::string message_header) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + printer.Print("#import \"PBgRPCClient.h\"\n"); + printer.Print("#import \"PBStub.h\"\n"); + vars["message_header"] = message_header; + printer.Print(vars, "#import \"$message_header$\"\n\n"); + printer.Print("@protocol GRXSource\n"); + printer.Print("@class GRXSource\n\n"); + vars["service_name"] = service->name(); + printer.Print("@protocol $service_name$Stub <NSObject>\n\n"); + printer.Print("#pragma mark Simple block handlers\n\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSimpleBlockSignature(&printer, service->method(i), &vars); + printer.Print(";\n"); + } + printer.Print("\n"); + printer.Print("#pragma mark Simple delegate handlers.\n\n"); + printer.Print("# TODO(jcanizales): Use high-level snippets to remove this duplication."); + for (int i = 0; i < service->method_count(); i++) { + PrintSimpleDelegateSignature(&printer, service->method(i), &vars); + printer.Print(";\n"); + } + printer.Print("\n"); + printer.Print("#pragma mark Advanced handlers.\n\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintAdvancedSignature(&printer, service->method(i), &vars); + printer.Print(";\n"); + } + printer.Print("\n"); + printer.Print("@end\n\n"); + printer.Print("// Basic stub that only does marshalling and parsing\n"); + printer.Print(vars, "@interface $service_name$Stub :" + " PBStub<$service_name$Stub>\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host;\n"); + printer.Print("@end\n"); + return output; +} + +grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service) { + grpc::string output; + grpc::protobuf::io::StringOutputStream output_stream(&output); + grpc::protobuf::io::Printer printer(&output_stream, '$'); + std::map<grpc::string, grpc::string> vars; + vars["service_name"] = service->name(); + printer.Print(vars, "#import \"$service_name$Stub.pb.h\"\n"); + printer.Print("#import \"PBGeneratedMessage+GRXSource.h\"\n\n"); + vars["full_name"] = service->full_name(); + printer.Print(vars, + "static NSString *const kInterface = @\"$full_name$\";\n"); + printer.Print("@implementation $service_name$Stub\n\n"); + printer.Print("- (instancetype)initWithHost:(NSString *)host {\n"); + printer.Indent(); + printer.Print("if ((self = [super initWithHost:host " + "interface:kInterface])) {\n"); + printer.Print("}\n"); + printer.Print("return self;\n"); + printer.Outdent(); + printer.Print("}\n\n"); + printer.Print("#pragma mark Simple block handlers.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodSimpleBlock(&printer, service->method(i), &vars); + } + printer.Print("\n"); + printer.Print("#pragma mark Simple delegate handlers.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodSimpleDelegate(&printer, service->method(i), &vars); + } + printer.Print("\n"); + printer.Print("#pragma mark Advanced handlers.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodAdvanced(&printer, service->method(i), &vars); + } + printer.Print("\n"); + printer.Print("#pragma mark Handlers for subclasses " + "(stub wrappers) to override.\n"); + for (int i = 0; i < service->method_count(); i++) { + PrintSourceMethodHandler(&printer, service->method(i), &vars); + } + printer.Print("@end\n"); + return output; +} + +} // namespace grpc_objective_c_generator diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h new file mode 100644 index 0000000000..93c730b34e --- /dev/null +++ b/src/compiler/objective_c_generator.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H +#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H + +#include "src/compiler/config.h" + +namespace grpc_objective_c_generator { + +grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service, + const grpc::string message_header); + +grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service); + +} // namespace grpc_objective_c_generator + +#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_H diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h new file mode 100644 index 0000000000..6a7c13991f --- /dev/null +++ b/src/compiler/objective_c_generator_helpers.h @@ -0,0 +1,58 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H +#define GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H + +#include <map> +#include "src/compiler/config.h" +#include "src/compiler/generator_helpers.h" + +namespace grpc_objective_c_generator { + +const grpc::string prefix = "PBG"; + +inline grpc::string MessageHeaderName(const grpc::protobuf::FileDescriptor *file) { + return grpc_generator::FileNameInUpperCamel(file) + ".pb.h"; +} + +inline grpc::string StubFileName(grpc::string service_name) { + return prefix + service_name + "Stub"; +} + +inline grpc::string PrefixedName(grpc::string name) { + return prefix + name; +} + +} +#endif // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc new file mode 100644 index 0000000000..eebce0cd20 --- /dev/null +++ b/src/compiler/objective_c_plugin.cc @@ -0,0 +1,98 @@ +/* + * + * 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. + * + */ + +// Generates Objective C gRPC service interface out of Protobuf IDL. + +#include <memory> + +#include "src/compiler/config.h" +#include "src/compiler/objective_c_generator.h" +#include "src/compiler/objective_c_generator_helpers.h" + +class ObjectiveCGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { + public: + ObjectiveCGrpcGenerator() {} + virtual ~ObjectiveCGrpcGenerator() {} + + virtual bool Generate(const grpc::protobuf::FileDescriptor *file, + const grpc::string ¶meter, + grpc::protobuf::compiler::GeneratorContext *context, + grpc::string *error) const { + + if (file->service_count() == 0) { + // No services. Do nothing. + return true; + } + + for (int i = 0; i < file->service_count(); i++) { + const grpc::protobuf::ServiceDescriptor *service = file->service(i); + grpc::string file_name = grpc_objective_c_generator::StubFileName( + service->name()); + + // Generate .pb.h + grpc::string header_code = grpc_objective_c_generator::GetHeader( + service, grpc_objective_c_generator::MessageHeaderName(file)); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> header_output( + context->Open(file_name + ".pb.h")); + grpc::protobuf::io::CodedOutputStream header_coded_out( + header_output.get()); + header_coded_out.WriteRaw(header_code.data(), header_code.size()); + + // Generate .pb.m + grpc::string source_code = grpc_objective_c_generator::GetSource(service); + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> source_output( + context->Open(file_name + ".pb.m")); + grpc::protobuf::io::CodedOutputStream source_coded_out( + source_output.get()); + source_coded_out.WriteRaw(source_code.data(), source_code.size()); + } + + return true; + } + + private: + // Insert the given code into the given file at the given insertion point. + void Insert(grpc::protobuf::compiler::GeneratorContext *context, + const grpc::string &filename, const grpc::string &insertion_point, + const grpc::string &code) const { + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output( + context->OpenForInsert(filename, insertion_point)); + grpc::protobuf::io::CodedOutputStream coded_out(output.get()); + coded_out.WriteRaw(code.data(), code.size()); + } +}; + +int main(int argc, char *argv[]) { + ObjectiveCGrpcGenerator generator; + return grpc::protobuf::compiler::PluginMain(argc, argv, &generator); +} diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index e4f85450f5..72149bc4e3 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -36,25 +36,28 @@ #include <cctype> #include <cstring> #include <map> +#include <memory> #include <ostream> #include <sstream> +#include <tuple> #include <vector> +#include "grpc++/config.h" +#include "src/compiler/config.h" #include "src/compiler/generator_helpers.h" #include "src/compiler/python_generator.h" -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/descriptor.h> using grpc_generator::StringReplace; using grpc_generator::StripProto; -using google::protobuf::Descriptor; -using google::protobuf::FileDescriptor; -using google::protobuf::MethodDescriptor; -using google::protobuf::ServiceDescriptor; -using google::protobuf::io::Printer; -using google::protobuf::io::StringOutputStream; +using grpc::protobuf::Descriptor; +using grpc::protobuf::FileDescriptor; +using grpc::protobuf::MethodDescriptor; +using grpc::protobuf::ServiceDescriptor; +using grpc::protobuf::compiler::GeneratorContext; +using grpc::protobuf::io::CodedOutputStream; +using grpc::protobuf::io::Printer; +using grpc::protobuf::io::StringOutputStream; +using grpc::protobuf::io::ZeroCopyOutputStream; using std::initializer_list; using std::make_pair; using std::map; @@ -63,6 +66,41 @@ using std::replace; using std::vector; namespace grpc_python_generator { + +PythonGrpcGenerator::PythonGrpcGenerator(const GeneratorConfiguration& config) + : config_(config) {} + +PythonGrpcGenerator::~PythonGrpcGenerator() {} + +bool PythonGrpcGenerator::Generate( + const FileDescriptor* file, const grpc::string& parameter, + GeneratorContext* context, grpc::string* error) const { + // Get output file name. + grpc::string file_name; + static const int proto_suffix_length = strlen(".proto"); + if (file->name().size() > static_cast<size_t>(proto_suffix_length) && + file->name().find_last_of(".proto") == file->name().size() - 1) { + file_name = file->name().substr( + 0, file->name().size() - proto_suffix_length) + "_pb2.py"; + } else { + *error = "Invalid proto file name. Proto file must end with .proto"; + return false; + } + + std::unique_ptr<ZeroCopyOutputStream> output( + context->OpenForInsert(file_name, "module_scope")); + CodedOutputStream coded_out(output.get()); + bool success = false; + grpc::string code = ""; + tie(success, code) = grpc_python_generator::GetServices(file, config_); + if (success) { + coded_out.WriteRaw(code.data(), code.size()); + return true; + } else { + return false; + } +} + namespace { ////////////////////////////////// // BEGIN FORMATTING BOILERPLATE // @@ -70,14 +108,15 @@ namespace { // Converts an initializer list of the form { key0, value0, key1, value1, ... } // into a map of key* to value*. Is merely a readability helper for later code. -map<std::string, std::string> ListToDict(const initializer_list<std::string>& values) { +map<grpc::string, grpc::string> ListToDict( + const initializer_list<grpc::string>& values) { assert(values.size() % 2 == 0); - map<std::string, std::string> value_map; + map<grpc::string, grpc::string> value_map; auto value_iter = values.begin(); for (unsigned i = 0; i < values.size()/2; ++i) { - std::string key = *value_iter; + grpc::string key = *value_iter; ++value_iter; - std::string value = *value_iter; + grpc::string value = *value_iter; value_map[key] = value; ++value_iter; } @@ -111,8 +150,8 @@ class IndentScope { bool PrintServicer(const ServiceDescriptor* service, Printer* out) { - std::string doc = "<fill me in later!>"; - map<std::string, std::string> dict = ListToDict({ + grpc::string doc = "<fill me in later!>"; + map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), "Documentation", doc, }); @@ -123,7 +162,7 @@ bool PrintServicer(const ServiceDescriptor* service, out->Print("__metaclass__ = abc.ABCMeta\n"); for (int i = 0; i < service->method_count(); ++i) { auto meth = service->method(i); - std::string arg_name = meth->client_streaming() ? + grpc::string arg_name = meth->client_streaming() ? "request_iterator" : "request"; out->Print("@abc.abstractmethod\n"); out->Print("def $Method$(self, $ArgName$, context):\n", @@ -138,8 +177,8 @@ bool PrintServicer(const ServiceDescriptor* service, } bool PrintServer(const ServiceDescriptor* service, Printer* out) { - std::string doc = "<fill me in later!>"; - map<std::string, std::string> dict = ListToDict({ + grpc::string doc = "<fill me in later!>"; + map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), "Documentation", doc, }); @@ -167,8 +206,8 @@ bool PrintServer(const ServiceDescriptor* service, Printer* out) { bool PrintStub(const ServiceDescriptor* service, Printer* out) { - std::string doc = "<fill me in later!>"; - map<std::string, std::string> dict = ListToDict({ + grpc::string doc = "<fill me in later!>"; + map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), "Documentation", doc, }); @@ -179,7 +218,7 @@ bool PrintStub(const ServiceDescriptor* service, out->Print("__metaclass__ = abc.ABCMeta\n"); for (int i = 0; i < service->method_count(); ++i) { const MethodDescriptor* meth = service->method(i); - std::string arg_name = meth->client_streaming() ? + grpc::string arg_name = meth->client_streaming() ? "request_iterator" : "request"; auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name}); out->Print("@abc.abstractmethod\n"); @@ -196,29 +235,29 @@ bool PrintStub(const ServiceDescriptor* service, // TODO(protobuf team): Export `ModuleName` from protobuf's // `src/google/protobuf/compiler/python/python_generator.cc` file. -std::string ModuleName(const std::string& filename) { - std::string basename = StripProto(filename); +grpc::string ModuleName(const grpc::string& filename) { + grpc::string basename = StripProto(filename); basename = StringReplace(basename, "-", "_"); basename = StringReplace(basename, "/", "."); return basename + "_pb2"; } bool GetModuleAndMessagePath(const Descriptor* type, - pair<std::string, std::string>* out) { + pair<grpc::string, grpc::string>* out) { const Descriptor* path_elem_type = type; vector<const Descriptor*> message_path; do { message_path.push_back(path_elem_type); path_elem_type = path_elem_type->containing_type(); } while (path_elem_type != nullptr); - std::string file_name = type->file()->name(); + 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) && file_name.find_last_of(".proto") == file_name.size() - 1)) { return false; } - std::string module = ModuleName(file_name); - std::string message_type; + grpc::string module = ModuleName(file_name); + grpc::string message_type; for (auto path_iter = message_path.rbegin(); path_iter != message_path.rend(); ++path_iter) { message_type += (*path_iter)->name() + "."; @@ -229,28 +268,30 @@ bool GetModuleAndMessagePath(const Descriptor* type, return true; } -bool PrintServerFactory(const std::string& package_qualified_service_name, +bool PrintServerFactory(const grpc::string& package_qualified_service_name, const ServiceDescriptor* service, Printer* out) { out->Print("def early_adopter_create_$Service$_server(servicer, port, " - "root_certificates, key_chain_pairs):\n", + "private_key=None, certificate_chain=None):\n", "Service", service->name()); { IndentScope raii_create_server_indent(out); - map<std::string, std::string> method_description_constructors; - map<std::string, pair<std::string, std::string>> input_message_modules_and_classes; - map<std::string, pair<std::string, std::string>> output_message_modules_and_classes; + map<grpc::string, grpc::string> method_description_constructors; + map<grpc::string, pair<grpc::string, grpc::string>> + input_message_modules_and_classes; + map<grpc::string, pair<grpc::string, grpc::string>> + output_message_modules_and_classes; for (int i = 0; i < service->method_count(); ++i) { const MethodDescriptor* method = service->method(i); - const std::string method_description_constructor = - std::string(method->client_streaming() ? "stream_" : "unary_") + - std::string(method->server_streaming() ? "stream_" : "unary_") + + const grpc::string method_description_constructor = + grpc::string(method->client_streaming() ? "stream_" : "unary_") + + grpc::string(method->server_streaming() ? "stream_" : "unary_") + "service_description"; - pair<std::string, std::string> input_message_module_and_class; + pair<grpc::string, grpc::string> input_message_module_and_class; if (!GetModuleAndMessagePath(method->input_type(), &input_message_module_and_class)) { return false; } - pair<std::string, std::string> output_message_module_and_class; + pair<grpc::string, grpc::string> output_message_module_and_class; if (!GetModuleAndMessagePath(method->output_type(), &output_message_module_and_class)) { return false; @@ -268,17 +309,20 @@ bool PrintServerFactory(const std::string& package_qualified_service_name, make_pair(method->name(), output_message_module_and_class)); } out->Print("method_service_descriptions = {\n"); - for (auto& name_and_description_constructor : - method_description_constructors) { + for (auto name_and_description_constructor = + method_description_constructors.begin(); + name_and_description_constructor != + method_description_constructors.end(); + name_and_description_constructor++) { IndentScope raii_descriptions_indent(out); - const std::string method_name = name_and_description_constructor.first; + const grpc::string method_name = name_and_description_constructor->first; auto input_message_module_and_class = input_message_modules_and_classes.find(method_name); auto output_message_module_and_class = output_message_modules_and_classes.find(method_name); out->Print("\"$Method$\": utilities.$Constructor$(\n", "Method", method_name, "Constructor", - name_and_description_constructor.second); + name_and_description_constructor->second); { IndentScope raii_description_arguments_indent(out); out->Print("servicer.$Method$,\n", "Method", method_name); @@ -295,38 +339,43 @@ bool PrintServerFactory(const std::string& package_qualified_service_name, } out->Print("}\n"); out->Print( - "return implementations.secure_server(" + "return implementations.server(" "\"$PackageQualifiedServiceName$\"," - " method_service_descriptions, port, root_certificates," - " key_chain_pairs)\n", + " method_service_descriptions, port, private_key=private_key," + " certificate_chain=certificate_chain)\n", "PackageQualifiedServiceName", package_qualified_service_name); } return true; } -bool PrintStubFactory(const std::string& package_qualified_service_name, +bool PrintStubFactory(const grpc::string& package_qualified_service_name, const ServiceDescriptor* service, Printer* out) { - map<std::string, std::string> dict = ListToDict({ + map<grpc::string, grpc::string> dict = ListToDict({ "Service", service->name(), }); - out->Print(dict, "def early_adopter_create_$Service$_stub(host, port):\n"); + out->Print(dict, "def early_adopter_create_$Service$_stub(host, port," + " metadata_transformer=None," + " secure=False, root_certificates=None, private_key=None," + " certificate_chain=None, server_host_override=None):\n"); { IndentScope raii_create_server_indent(out); - map<std::string, std::string> method_description_constructors; - map<std::string, pair<std::string, std::string>> input_message_modules_and_classes; - map<std::string, pair<std::string, std::string>> output_message_modules_and_classes; + map<grpc::string, grpc::string> method_description_constructors; + map<grpc::string, pair<grpc::string, grpc::string>> + input_message_modules_and_classes; + map<grpc::string, pair<grpc::string, grpc::string>> + output_message_modules_and_classes; for (int i = 0; i < service->method_count(); ++i) { const MethodDescriptor* method = service->method(i); - const std::string method_description_constructor = - std::string(method->client_streaming() ? "stream_" : "unary_") + - std::string(method->server_streaming() ? "stream_" : "unary_") + + const grpc::string method_description_constructor = + grpc::string(method->client_streaming() ? "stream_" : "unary_") + + grpc::string(method->server_streaming() ? "stream_" : "unary_") + "invocation_description"; - pair<std::string, std::string> input_message_module_and_class; + pair<grpc::string, grpc::string> input_message_module_and_class; if (!GetModuleAndMessagePath(method->input_type(), &input_message_module_and_class)) { return false; } - pair<std::string, std::string> output_message_module_and_class; + pair<grpc::string, grpc::string> output_message_module_and_class; if (!GetModuleAndMessagePath(method->output_type(), &output_message_module_and_class)) { return false; @@ -344,17 +393,20 @@ bool PrintStubFactory(const std::string& package_qualified_service_name, make_pair(method->name(), output_message_module_and_class)); } out->Print("method_invocation_descriptions = {\n"); - for (auto& name_and_description_constructor : - method_description_constructors) { + for (auto name_and_description_constructor = + method_description_constructors.begin(); + name_and_description_constructor != + method_description_constructors.end(); + name_and_description_constructor++) { IndentScope raii_descriptions_indent(out); - const std::string method_name = name_and_description_constructor.first; + const grpc::string method_name = name_and_description_constructor->first; auto input_message_module_and_class = input_message_modules_and_classes.find(method_name); auto output_message_module_and_class = output_message_modules_and_classes.find(method_name); out->Print("\"$Method$\": utilities.$Constructor$(\n", "Method", method_name, "Constructor", - name_and_description_constructor.second); + name_and_description_constructor->second); { IndentScope raii_description_arguments_indent(out); out->Print( @@ -370,30 +422,37 @@ bool PrintStubFactory(const std::string& package_qualified_service_name, } out->Print("}\n"); out->Print( - "return implementations.insecure_stub(" + "return implementations.stub(" "\"$PackageQualifiedServiceName$\"," - " method_invocation_descriptions, host, port)\n", + " method_invocation_descriptions, host, port," + " metadata_transformer=metadata_transformer, secure=secure," + " root_certificates=root_certificates, private_key=private_key," + " certificate_chain=certificate_chain," + " server_host_override=server_host_override)\n", "PackageQualifiedServiceName", package_qualified_service_name); } return true; } -bool PrintPreamble(const FileDescriptor* file, Printer* out) { +bool PrintPreamble(const FileDescriptor* file, + const GeneratorConfiguration& config, Printer* out) { out->Print("import abc\n"); - out->Print("from grpc.early_adopter import implementations\n"); + out->Print("from $Package$ import implementations\n", + "Package", config.implementations_package_root); out->Print("from grpc.framework.alpha import utilities\n"); return true; } } // namespace -pair<bool, std::string> GetServices(const FileDescriptor* file) { - std::string output; +pair<bool, grpc::string> GetServices(const FileDescriptor* file, + const GeneratorConfiguration& config) { + grpc::string output; { // Scope the output stream so it closes and finalizes output to the string. StringOutputStream output_stream(&output); Printer out(&output_stream, '$'); - if (!PrintPreamble(file, &out)) { + if (!PrintPreamble(file, config, &out)) { return make_pair(false, ""); } auto package = file->package(); diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h index df29ca17e3..b47f3c1243 100644 --- a/src/compiler/python_generator.h +++ b/src/compiler/python_generator.h @@ -34,18 +34,34 @@ #ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H #define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H -#include <string> #include <utility> -namespace google { -namespace protobuf { -class FileDescriptor; -} // namespace protobuf -} // namespace google +#include "src/compiler/config.h" namespace grpc_python_generator { -std::pair<bool, std::string> GetServices(const google::protobuf::FileDescriptor* file); +// Data pertaining to configuration of the generator with respect to anything +// that may be used internally at Google. +struct GeneratorConfiguration { + grpc::string implementations_package_root; +}; + +class PythonGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { + public: + PythonGrpcGenerator(const GeneratorConfiguration& config); + ~PythonGrpcGenerator(); + + bool Generate(const grpc::protobuf::FileDescriptor* file, + const grpc::string& parameter, + grpc::protobuf::compiler::GeneratorContext* context, + grpc::string* error) const; + private: + GeneratorConfiguration config_; +}; + +std::pair<bool, grpc::string> GetServices( + const grpc::protobuf::FileDescriptor* file, + const GeneratorConfiguration& config); } // namespace grpc_python_generator diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc index e7d172f7bf..d1f49442da 100644 --- a/src/compiler/python_plugin.cc +++ b/src/compiler/python_plugin.cc @@ -33,60 +33,12 @@ // Generates a Python gRPC service interface out of Protobuf IDL. -#include <cstring> -#include <memory> -#include <string> -#include <tuple> - +#include "src/compiler/config.h" #include "src/compiler/python_generator.h" -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/compiler/plugin.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.h> - -using google::protobuf::FileDescriptor; -using google::protobuf::compiler::CodeGenerator; -using google::protobuf::compiler::GeneratorContext; -using google::protobuf::compiler::PluginMain; -using google::protobuf::io::CodedOutputStream; -using google::protobuf::io::ZeroCopyOutputStream; - -class PythonGrpcGenerator : public CodeGenerator { - public: - PythonGrpcGenerator() {} - ~PythonGrpcGenerator() {} - - bool Generate(const FileDescriptor* file, const std::string& parameter, - GeneratorContext* context, std::string* error) const { - // Get output file name. - std::string file_name; - static const int proto_suffix_length = strlen(".proto"); - if (file->name().size() > static_cast<size_t>(proto_suffix_length) && - file->name().find_last_of(".proto") == file->name().size() - 1) { - file_name = file->name().substr( - 0, file->name().size() - proto_suffix_length) + "_pb2.py"; - } else { - *error = "Invalid proto file name. Proto file must end with .proto"; - return false; - } - - std::unique_ptr<ZeroCopyOutputStream> output( - context->OpenForInsert(file_name, "module_scope")); - CodedOutputStream coded_out(output.get()); - bool success = false; - std::string code = ""; - tie(success, code) = grpc_python_generator::GetServices(file); - if (success) { - coded_out.WriteRaw(code.data(), code.size()); - return true; - } else { - return false; - } - } -}; int main(int argc, char* argv[]) { - PythonGrpcGenerator generator; - return PluginMain(argc, argv, &generator); + grpc_python_generator::GeneratorConfiguration config; + config.implementations_package_root = "grpc.early_adopter"; + grpc_python_generator::PythonGrpcGenerator generator(config); + return grpc::protobuf::compiler::PluginMain(argc, argv, &generator); } diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc index 32b6a8d8e4..a0bb92848b 100644 --- a/src/compiler/ruby_generator.cc +++ b/src/compiler/ruby_generator.cc @@ -32,24 +32,20 @@ */ #include <cctype> -#include <string> #include <map> #include <vector> +#include "src/compiler/config.h" #include "src/compiler/ruby_generator.h" #include "src/compiler/ruby_generator_helpers-inl.h" #include "src/compiler/ruby_generator_map-inl.h" #include "src/compiler/ruby_generator_string-inl.h" -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream_impl_lite.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/descriptor.h> - -using google::protobuf::FileDescriptor; -using google::protobuf::ServiceDescriptor; -using google::protobuf::MethodDescriptor; -using google::protobuf::io::Printer; -using google::protobuf::io::StringOutputStream; + +using grpc::protobuf::FileDescriptor; +using grpc::protobuf::ServiceDescriptor; +using grpc::protobuf::MethodDescriptor; +using grpc::protobuf::io::Printer; +using grpc::protobuf::io::StringOutputStream; using std::map; using std::vector; @@ -57,38 +53,38 @@ namespace grpc_ruby_generator { namespace { // Prints out the method using the ruby gRPC DSL. -void PrintMethod(const MethodDescriptor *method, const std::string &package, +void PrintMethod(const MethodDescriptor *method, const grpc::string &package, Printer *out) { - std::string input_type = RubyTypeOf(method->input_type()->name(), package); + grpc::string input_type = RubyTypeOf(method->input_type()->name(), package); if (method->client_streaming()) { input_type = "stream(" + input_type + ")"; } - std::string output_type = RubyTypeOf(method->output_type()->name(), package); + grpc::string output_type = RubyTypeOf(method->output_type()->name(), package); if (method->server_streaming()) { output_type = "stream(" + output_type + ")"; } - std::map<std::string, std::string> method_vars = + std::map<grpc::string, grpc::string> method_vars = ListToDict({"mth.name", method->name(), "input.type", input_type, "output.type", output_type, }); out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n"); } // Prints out the service using the ruby gRPC DSL. -void PrintService(const ServiceDescriptor *service, const std::string &package, +void PrintService(const ServiceDescriptor *service, const grpc::string &package, Printer *out) { if (service->method_count() == 0) { return; } // Begin the service module - std::map<std::string, std::string> module_vars = + std::map<grpc::string, grpc::string> module_vars = ListToDict({"module.name", CapitalizeFirst(service->name()), }); out->Print(module_vars, "module $module.name$\n"); out->Indent(); // TODO(temiola): add documentation - std::string doc = "TODO: add proto service documentation here"; - std::map<std::string, std::string> template_vars = + grpc::string doc = "TODO: add proto service documentation here"; + std::map<grpc::string, grpc::string> template_vars = ListToDict({"Documentation", doc, }); out->Print("\n"); out->Print(template_vars, "# $Documentation$\n"); @@ -101,7 +97,7 @@ void PrintService(const ServiceDescriptor *service, const std::string &package, out->Print("\n"); out->Print("self.marshal_class_method = :encode\n"); out->Print("self.unmarshal_class_method = :decode\n"); - std::map<std::string, std::string> pkg_vars = + std::map<grpc::string, grpc::string> pkg_vars = ListToDict({"service.name", service->name(), "pkg.name", package, }); out->Print(pkg_vars, "self.service_name = '$pkg.name$.$service.name$'\n"); out->Print("\n"); @@ -121,8 +117,8 @@ void PrintService(const ServiceDescriptor *service, const std::string &package, } // namespace -std::string GetServices(const FileDescriptor *file) { - std::string output; +grpc::string GetServices(const FileDescriptor *file) { + grpc::string output; StringOutputStream output_stream(&output); Printer out(&output_stream, '$'); @@ -133,7 +129,7 @@ std::string GetServices(const FileDescriptor *file) { } // Write out a file header. - std::map<std::string, std::string> header_comment_vars = ListToDict( + std::map<grpc::string, grpc::string> header_comment_vars = ListToDict( {"file.name", file->name(), "file.package", file->package(), }); out.Print("# Generated by the protocol buffer compiler. DO NOT EDIT!\n"); out.Print(header_comment_vars, @@ -144,15 +140,15 @@ std::string GetServices(const FileDescriptor *file) { // Write out require statemment to import the separately generated file // that defines the messages used by the service. This is generated by the // main ruby plugin. - std::map<std::string, std::string> dep_vars = + std::map<grpc::string, grpc::string> dep_vars = ListToDict({"dep.name", MessagesRequireName(file), }); out.Print(dep_vars, "require '$dep.name$'\n"); // Write out services within the modules out.Print("\n"); - std::vector<std::string> modules = Split(file->package(), '.'); + std::vector<grpc::string> modules = Split(file->package(), '.'); for (size_t i = 0; i < modules.size(); ++i) { - std::map<std::string, std::string> module_vars = + std::map<grpc::string, grpc::string> module_vars = ListToDict({"module.name", CapitalizeFirst(modules[i]), }); out.Print(module_vars, "module $module.name$\n"); out.Indent(); diff --git a/src/compiler/ruby_generator.h b/src/compiler/ruby_generator.h index 4dd38e0c27..a2ab36d4d9 100644 --- a/src/compiler/ruby_generator.h +++ b/src/compiler/ruby_generator.h @@ -34,17 +34,11 @@ #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H -#include <string> - -namespace google { -namespace protobuf { -class FileDescriptor; -} // namespace protobuf -} // namespace google +#include "src/compiler/config.h" namespace grpc_ruby_generator { -std::string GetServices(const google::protobuf::FileDescriptor *file); +grpc::string GetServices(const grpc::protobuf::FileDescriptor *file); } // namespace grpc_ruby_generator diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h index f3a087b3f8..9da7cab3c7 100644 --- a/src/compiler/ruby_generator_helpers-inl.h +++ b/src/compiler/ruby_generator_helpers-inl.h @@ -34,15 +34,13 @@ #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H -#include <string> - -#include <google/protobuf/descriptor.h> +#include "src/compiler/config.h" #include "src/compiler/ruby_generator_string-inl.h" namespace grpc_ruby_generator { -inline bool ServicesFilename(const google::protobuf::FileDescriptor *file, - std::string *file_name_or_error) { +inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file, + grpc::string *file_name_or_error) { // Get output file name. static const unsigned proto_suffix_length = 6; // length of ".proto" if (file->name().size() > proto_suffix_length && @@ -57,8 +55,8 @@ inline bool ServicesFilename(const google::protobuf::FileDescriptor *file, } } -inline std::string MessagesRequireName( - const google::protobuf::FileDescriptor *file) { +inline grpc::string MessagesRequireName( + const grpc::protobuf::FileDescriptor *file) { return Replace(file->name(), ".proto", ""); } diff --git a/src/compiler/ruby_generator_map-inl.h b/src/compiler/ruby_generator_map-inl.h index f902b6d98f..6b87774f21 100644 --- a/src/compiler/ruby_generator_map-inl.h +++ b/src/compiler/ruby_generator_map-inl.h @@ -34,11 +34,12 @@ #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H +#include "src/compiler/config.h" + #include <iostream> #include <initializer_list> #include <map> #include <ostream> // NOLINT -#include <string> #include <vector> using std::initializer_list; @@ -49,18 +50,18 @@ namespace grpc_ruby_generator { // Converts an initializer list of the form { key0, value0, key1, value1, ... } // into a map of key* to value*. Is merely a readability helper for later code. -inline std::map<std::string, std::string> ListToDict( - const initializer_list<std::string> &values) { +inline std::map<grpc::string, grpc::string> ListToDict( + const initializer_list<grpc::string> &values) { if (values.size() % 2 != 0) { std::cerr << "Not every 'key' has a value in `values`." << std::endl; } - std::map<std::string, std::string> value_map; + std::map<grpc::string, grpc::string> value_map; auto value_iter = values.begin(); for (unsigned i = 0; i < values.size() / 2; ++i) { - std::string key = *value_iter; + grpc::string key = *value_iter; ++value_iter; - std::string value = *value_iter; + grpc::string value = *value_iter; value_map[key] = value; ++value_iter; } diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h index bdd314c16e..8da3a88da2 100644 --- a/src/compiler/ruby_generator_string-inl.h +++ b/src/compiler/ruby_generator_string-inl.h @@ -34,8 +34,9 @@ #ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H +#include "src/compiler/config.h" + #include <algorithm> -#include <string> #include <sstream> #include <vector> @@ -45,10 +46,10 @@ using std::transform; namespace grpc_ruby_generator { // Split splits a string using char into elems. -inline std::vector<std::string> &Split(const std::string &s, char delim, - std::vector<std::string> *elems) { +inline std::vector<grpc::string> &Split(const grpc::string &s, char delim, + std::vector<grpc::string> *elems) { std::stringstream ss(s); - std::string item; + grpc::string item; while (getline(ss, item, delim)) { elems->push_back(item); } @@ -56,17 +57,17 @@ inline std::vector<std::string> &Split(const std::string &s, char delim, } // Split splits a string using char, returning the result in a vector. -inline std::vector<std::string> Split(const std::string &s, char delim) { - std::vector<std::string> elems; +inline std::vector<grpc::string> Split(const grpc::string &s, char delim) { + std::vector<grpc::string> elems; Split(s, delim, &elems); return elems; } // Replace replaces from with to in s. -inline std::string Replace(std::string s, const std::string &from, - const std::string &to) { +inline grpc::string Replace(grpc::string s, const grpc::string &from, + const grpc::string &to) { size_t start_pos = s.find(from); - if (start_pos == std::string::npos) { + if (start_pos == grpc::string::npos) { return s; } s.replace(start_pos, from.length(), to); @@ -74,10 +75,10 @@ inline std::string Replace(std::string s, const std::string &from, } // ReplaceAll replaces all instances of search with replace in s. -inline std::string ReplaceAll(std::string s, const std::string &search, - const std::string &replace) { +inline grpc::string ReplaceAll(grpc::string s, const grpc::string &search, + const grpc::string &replace) { size_t pos = 0; - while ((pos = s.find(search, pos)) != std::string::npos) { + while ((pos = s.find(search, pos)) != grpc::string::npos) { s.replace(pos, search.length(), replace); pos += replace.length(); } @@ -85,10 +86,10 @@ inline std::string ReplaceAll(std::string s, const std::string &search, } // ReplacePrefix replaces from with to in s if search is a prefix of s. -inline bool ReplacePrefix(std::string *s, const std::string &from, - const std::string &to) { +inline bool ReplacePrefix(grpc::string *s, const grpc::string &from, + const grpc::string &to) { size_t start_pos = s->find(from); - if (start_pos == std::string::npos || start_pos != 0) { + if (start_pos == grpc::string::npos || start_pos != 0) { return false; } s->replace(start_pos, from.length(), to); @@ -96,7 +97,7 @@ inline bool ReplacePrefix(std::string *s, const std::string &from, } // CapitalizeFirst capitalizes the first char in a string. -inline std::string CapitalizeFirst(std::string s) { +inline grpc::string CapitalizeFirst(grpc::string s) { if (s.empty()) { return s; } @@ -105,15 +106,15 @@ inline std::string CapitalizeFirst(std::string s) { } // RubyTypeOf updates a proto type to the required ruby equivalent. -inline std::string RubyTypeOf(const std::string &a_type, - const std::string &package) { - std::string res(a_type); +inline grpc::string RubyTypeOf(const grpc::string &a_type, + const grpc::string &package) { + grpc::string res(a_type); ReplacePrefix(&res, package, ""); // remove the leading package if present ReplacePrefix(&res, ".", ""); // remove the leading . (no package) - if (res.find('.') == std::string::npos) { + if (res.find('.') == grpc::string::npos) { return res; } else { - std::vector<std::string> prefixes_and_type = Split(res, '.'); + std::vector<grpc::string> prefixes_and_type = Split(res, '.'); for (unsigned int i = 0; i < prefixes_and_type.size(); ++i) { if (i != 0) { res += "::"; // switch '.' to the ruby module delim diff --git a/src/compiler/ruby_plugin.cc b/src/compiler/ruby_plugin.cc index 4a6e9f7a5d..bd10d46e9c 100644 --- a/src/compiler/ruby_plugin.cc +++ b/src/compiler/ruby_plugin.cc @@ -32,43 +32,35 @@ */ // Generates Ruby gRPC service interface out of Protobuf IDL. -// -// This is a Proto2 compiler plugin. See net/proto2/compiler/proto/plugin.proto -// and net/proto2/compiler/public/plugin.h for more information on plugins. #include <memory> -#include <string> +#include "src/compiler/config.h" #include "src/compiler/ruby_generator.h" #include "src/compiler/ruby_generator_helpers-inl.h" -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/compiler/plugin.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/descriptor.h> -class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator { +class RubyGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { public: RubyGrpcGenerator() {} ~RubyGrpcGenerator() {} - bool Generate(const google::protobuf::FileDescriptor *file, - const std::string ¶meter, - google::protobuf::compiler::GeneratorContext *context, - std::string *error) const { - std::string code = grpc_ruby_generator::GetServices(file); + bool Generate(const grpc::protobuf::FileDescriptor *file, + const grpc::string ¶meter, + grpc::protobuf::compiler::GeneratorContext *context, + grpc::string *error) const { + grpc::string code = grpc_ruby_generator::GetServices(file); if (code.size() == 0) { return true; // don't generate a file if there are no services } // Get output file name. - std::string file_name; + grpc::string file_name; if (!grpc_ruby_generator::ServicesFilename(file, &file_name)) { return false; } - std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output( + std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output( context->Open(file_name)); - google::protobuf::io::CodedOutputStream coded_out(output.get()); + grpc::protobuf::io::CodedOutputStream coded_out(output.get()); coded_out.WriteRaw(code.data(), code.size()); return true; } @@ -76,5 +68,5 @@ class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator { int main(int argc, char *argv[]) { RubyGrpcGenerator generator; - return google::protobuf::compiler::PluginMain(argc, argv, &generator); + return grpc::protobuf::compiler::PluginMain(argc, argv, &generator); } diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index f565cbf3ae..9da8b333ca 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -189,7 +189,8 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem, /* translate host to :authority since :authority may be omitted */ grpc_mdelem *authority = grpc_mdelem_from_metadata_strings( - channeld->mdctx, channeld->authority_key, op->data.metadata->value); + channeld->mdctx, grpc_mdstr_ref(channeld->authority_key), + grpc_mdstr_ref(op->data.metadata->value)); grpc_mdelem_unref(op->data.metadata); op->data.metadata = authority; /* pass the event up */ diff --git a/src/core/httpcli/parser.c b/src/core/httpcli/parser.c index f4decda98a..7b2a62060c 100644 --- a/src/core/httpcli/parser.c +++ b/src/core/httpcli/parser.c @@ -177,6 +177,8 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) { } gpr_log(GPR_ERROR, "should never reach here"); abort(); + + return 0; } void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) { diff --git a/src/core/iomgr/iocp_windows.c b/src/core/iomgr/iocp_windows.c index 8b019e8049..aec626509a 100644 --- a/src/core/iomgr/iocp_windows.c +++ b/src/core/iomgr/iocp_windows.c @@ -52,10 +52,11 @@ static OVERLAPPED g_iocp_custom_overlap; static gpr_event g_shutdown_iocp; static gpr_event g_iocp_done; +static gpr_atm g_orphans = 0; static HANDLE g_iocp; -static int do_iocp_work() { +static void do_iocp_work() { BOOL success; DWORD bytes = 0; DWORD flags = 0; @@ -71,14 +72,14 @@ static int do_iocp_work() { gpr_time_to_millis(wait_time)); if (!success && !overlapped) { /* The deadline got attained. */ - return 0; + return; } GPR_ASSERT(completion_key && overlapped); if (overlapped == &g_iocp_custom_overlap) { if (completion_key == (ULONG_PTR) &g_iocp_kick_token) { /* We were awoken from a kick. */ gpr_log(GPR_DEBUG, "do_iocp_work - got a kick"); - return 1; + return; } gpr_log(GPR_ERROR, "Unknown custom completion key."); abort(); @@ -97,8 +98,13 @@ static int do_iocp_work() { } success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, FALSE, &flags); - gpr_log(GPR_DEBUG, "bytes: %u, flags: %u - op %s", bytes, flags, - success ? "succeeded" : "failed"); + gpr_log(GPR_DEBUG, "bytes: %u, flags: %u - op %s %s", bytes, flags, + success ? "succeeded" : "failed", socket->orphan ? "orphan" : ""); + if (socket->orphan) { + grpc_winsocket_destroy(socket); + gpr_atm_full_fetch_add(&g_orphans, -1); + return; + } info->bytes_transfered = bytes; info->wsa_error = success ? 0 : WSAGetLastError(); GPR_ASSERT(overlapped == &info->overlapped); @@ -113,12 +119,10 @@ static int do_iocp_work() { } gpr_mu_unlock(&socket->state_mu); if (f) f(opaque, 1); - - return 1; } static void iocp_loop(void *p) { - while (!gpr_event_get(&g_shutdown_iocp)) { + while (gpr_atm_acq_load(&g_orphans) || !gpr_event_get(&g_shutdown_iocp)) { grpc_maybe_call_delayed_callbacks(NULL, 1); do_iocp_work(); } @@ -138,13 +142,19 @@ void grpc_iocp_init(void) { gpr_thd_new(&id, iocp_loop, NULL, NULL); } -void grpc_iocp_shutdown(void) { +void grpc_iocp_kick(void) { BOOL success; - gpr_event_set(&g_shutdown_iocp, (void *)1); + success = PostQueuedCompletionStatus(g_iocp, 0, (ULONG_PTR) &g_iocp_kick_token, &g_iocp_custom_overlap); GPR_ASSERT(success); +} + +void grpc_iocp_shutdown(void) { + BOOL success; + gpr_event_set(&g_shutdown_iocp, (void *)1); + grpc_iocp_kick(); gpr_event_wait(&g_iocp_done, gpr_inf_future); success = CloseHandle(g_iocp); GPR_ASSERT(success); @@ -166,6 +176,10 @@ void grpc_iocp_add_socket(grpc_winsocket *socket) { GPR_ASSERT(ret == g_iocp); } +void grpc_iocp_socket_orphan(grpc_winsocket *socket) { + gpr_atm_full_fetch_add(&g_orphans, 1); +} + static void socket_notify_on_iocp(grpc_winsocket *socket, void(*cb)(void *, int), void *opaque, grpc_winsocket_callback_info *info) { diff --git a/src/core/iomgr/iocp_windows.h b/src/core/iomgr/iocp_windows.h index 33133193a1..fa3f5eee10 100644 --- a/src/core/iomgr/iocp_windows.h +++ b/src/core/iomgr/iocp_windows.h @@ -42,6 +42,7 @@ void grpc_iocp_init(void); void grpc_iocp_shutdown(void); void grpc_iocp_add_socket(grpc_winsocket *); +void grpc_iocp_socket_orphan(grpc_winsocket *); void grpc_socket_notify_on_write(grpc_winsocket *, void(*cb)(void *, int success), void *opaque); diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c index 058685b295..d0e6706fbd 100644 --- a/src/core/iomgr/iomgr.c +++ b/src/core/iomgr/iomgr.c @@ -117,7 +117,16 @@ void grpc_iomgr_shutdown(void) { gpr_mu_lock(&g_mu); } if (g_refs) { - if (gpr_cv_wait(&g_rcv, &g_mu, shutdown_deadline) && g_cbs_head == NULL) { + int timeout = 0; + gpr_timespec short_deadline = gpr_time_add(gpr_now(), + gpr_time_from_millis(100)); + while (gpr_cv_wait(&g_rcv, &g_mu, short_deadline) && g_cbs_head == NULL) { + if (gpr_time_cmp(gpr_now(), shutdown_deadline) > 0) { + timeout = 1; + break; + } + } + if (timeout) { gpr_log(GPR_DEBUG, "Failed to free %d iomgr objects before shutdown deadline: " "memory leaks are likely", diff --git a/src/core/iomgr/socket_windows.c b/src/core/iomgr/socket_windows.c index 99f38b0e03..22dad41783 100644 --- a/src/core/iomgr/socket_windows.c +++ b/src/core/iomgr/socket_windows.c @@ -55,7 +55,7 @@ grpc_winsocket *grpc_winsocket_create(SOCKET socket) { return r; } -void shutdown_op(grpc_winsocket_callback_info *info) { +static void shutdown_op(grpc_winsocket_callback_info *info) { if (!info->cb) return; grpc_iomgr_add_delayed_callback(info->cb, info->opaque, 0); } @@ -68,8 +68,13 @@ void grpc_winsocket_shutdown(grpc_winsocket *socket) { void grpc_winsocket_orphan(grpc_winsocket *socket) { gpr_log(GPR_DEBUG, "grpc_winsocket_orphan"); + grpc_iocp_socket_orphan(socket); + socket->orphan = 1; grpc_iomgr_unref(); closesocket(socket->socket); +} + +void grpc_winsocket_destroy(grpc_winsocket *socket) { gpr_mu_destroy(&socket->state_mu); gpr_free(socket); } diff --git a/src/core/iomgr/socket_windows.h b/src/core/iomgr/socket_windows.h index d4776ab10f..cbae91692c 100644 --- a/src/core/iomgr/socket_windows.h +++ b/src/core/iomgr/socket_windows.h @@ -57,12 +57,13 @@ typedef struct grpc_winsocket_callback_info { typedef struct grpc_winsocket { SOCKET socket; - int added_to_iocp; - grpc_winsocket_callback_info write_info; grpc_winsocket_callback_info read_info; gpr_mu state_mu; + + int added_to_iocp; + int orphan; } grpc_winsocket; /* Create a wrapped windows handle. @@ -71,5 +72,6 @@ grpc_winsocket *grpc_winsocket_create(SOCKET socket); void grpc_winsocket_shutdown(grpc_winsocket *socket); void grpc_winsocket_orphan(grpc_winsocket *socket); +void grpc_winsocket_destroy(grpc_winsocket *socket); #endif /* GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H */ diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h index 68ee85c5a7..66bb3ef701 100644 --- a/src/core/iomgr/tcp_server.h +++ b/src/core/iomgr/tcp_server.h @@ -71,6 +71,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, up when grpc_tcp_server_destroy is called. */ int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned index); -void grpc_tcp_server_destroy(grpc_tcp_server *server); +void grpc_tcp_server_destroy(grpc_tcp_server *server, + void (*shutdown_done)(void *shutdown_done_arg), + void *shutdown_done_arg); -#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */ +#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */ diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c index 90b7eb451d..895f85fc68 100644 --- a/src/core/iomgr/tcp_server_posix.c +++ b/src/core/iomgr/tcp_server_posix.c @@ -102,12 +102,18 @@ struct grpc_tcp_server { gpr_cv cv; /* active port count: how many ports are actually still listening */ - int active_ports; + size_t active_ports; + /* destroyed port count: how many ports are completely destroyed */ + size_t destroyed_ports; /* all listening ports */ server_port *ports; size_t nports; size_t port_capacity; + + /* shutdown callback */ + void (*shutdown_complete)(void *); + void *shutdown_complete_arg; }; grpc_tcp_server *grpc_tcp_server_create(void) { @@ -115,6 +121,7 @@ grpc_tcp_server *grpc_tcp_server_create(void) { gpr_mu_init(&s->mu); gpr_cv_init(&s->cv); s->active_ports = 0; + s->destroyed_ports = 0; s->cb = NULL; s->cb_arg = NULL; s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP); @@ -123,29 +130,64 @@ grpc_tcp_server *grpc_tcp_server_create(void) { return s; } -void grpc_tcp_server_destroy(grpc_tcp_server *s) { +static void finish_shutdown(grpc_tcp_server *s) { + s->shutdown_complete(s->shutdown_complete_arg); + + gpr_mu_destroy(&s->mu); + gpr_cv_destroy(&s->cv); + + gpr_free(s->ports); + gpr_free(s); +} + +static void destroyed_port(void *server, int success) { + grpc_tcp_server *s = server; + gpr_mu_lock(&s->mu); + s->destroyed_ports++; + if (s->destroyed_ports == s->nports) { + gpr_mu_unlock(&s->mu); + finish_shutdown(s); + } else { + gpr_mu_unlock(&s->mu); + } +} + +static void dont_care_about_shutdown_completion(void *ignored) {} + +void grpc_tcp_server_destroy( + grpc_tcp_server *s, void (*shutdown_complete)(void *shutdown_complete_arg), + void *shutdown_complete_arg) { size_t i; gpr_mu_lock(&s->mu); + + s->shutdown_complete = shutdown_complete + ? shutdown_complete + : dont_care_about_shutdown_completion; + s->shutdown_complete_arg = shutdown_complete_arg; + /* shutdown all fd's */ for (i = 0; i < s->nports; i++) { grpc_fd_shutdown(s->ports[i].emfd); } /* wait while that happens */ + /* TODO(ctiller): make this asynchronous also */ while (s->active_ports) { gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future); } gpr_mu_unlock(&s->mu); /* delete ALL the things */ - for (i = 0; i < s->nports; i++) { - server_port *sp = &s->ports[i]; - if (sp->addr.sockaddr.sa_family == AF_UNIX) { - unlink_if_unix_domain_socket(&sp->addr.un); + if (s->nports) { + for (i = 0; i < s->nports; i++) { + server_port *sp = &s->ports[i]; + if (sp->addr.sockaddr.sa_family == AF_UNIX) { + unlink_if_unix_domain_socket(&sp->addr.un); + } + grpc_fd_orphan(sp->emfd, destroyed_port, s); } - grpc_fd_orphan(sp->emfd, NULL, NULL); + } else { + finish_shutdown(s); } - gpr_free(s->ports); - gpr_free(s); } /* get max listen queue size on linux */ diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c index 0c3ab1dc91..a43d5670a4 100644 --- a/src/core/iomgr/tcp_server_windows.c +++ b/src/core/iomgr/tcp_server_windows.c @@ -92,7 +92,9 @@ grpc_tcp_server *grpc_tcp_server_create(void) { return s; } -void grpc_tcp_server_destroy(grpc_tcp_server *s) { +void grpc_tcp_server_destroy(grpc_tcp_server *s, + void (*shutdown_done)(void *shutdown_done_arg), + void *shutdown_done_arg) { size_t i; gpr_mu_lock(&s->mu); /* shutdown all fd's */ @@ -112,11 +114,15 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s) { } gpr_free(s->ports); gpr_free(s); + + if (shutdown_done) { + shutdown_done(shutdown_done_arg); + } } /* Prepare a recently-created socket for listening. */ -static int prepare_socket(SOCKET sock, - const struct sockaddr *addr, int addr_len) { +static int prepare_socket(SOCKET sock, const struct sockaddr *addr, + int addr_len) { struct sockaddr_storage sockname_temp; socklen_t sockname_len; @@ -147,15 +153,15 @@ static int prepare_socket(SOCKET sock, } sockname_len = sizeof(sockname_temp); - if (getsockname(sock, (struct sockaddr *) &sockname_temp, &sockname_len) - == SOCKET_ERROR) { + if (getsockname(sock, (struct sockaddr *)&sockname_temp, &sockname_len) == + SOCKET_ERROR) { char *utf8_message = gpr_format_message(WSAGetLastError()); gpr_log(GPR_ERROR, "getsockname: %s", utf8_message); gpr_free(utf8_message); goto error; } - return grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp); + return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); error: if (sock != INVALID_SOCKET) closesocket(sock); @@ -221,8 +227,7 @@ static void on_accept(void *arg, int success) { DWORD transfered_bytes = 0; DWORD flags; BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped, - &transfered_bytes, FALSE, - &flags); + &transfered_bytes, FALSE, &flags); if (!wsa_success) { char *utf8_message = gpr_format_message(WSAGetLastError()); gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message); @@ -257,9 +262,9 @@ static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock, if (sock == INVALID_SOCKET) return -1; - status = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, - &guid, sizeof(guid), &AcceptEx, sizeof(AcceptEx), - &ioctl_num_bytes, NULL, NULL); + status = + WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid), + &AcceptEx, sizeof(AcceptEx), &ioctl_num_bytes, NULL, NULL); if (status != 0) { char *utf8_message = gpr_format_message(WSAGetLastError()); @@ -307,9 +312,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, for (i = 0; i < s->nports; i++) { sockname_len = sizeof(sockname_temp); if (0 == getsockname(s->ports[i].socket->socket, - (struct sockaddr *) &sockname_temp, - &sockname_len)) { - port = grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp); + (struct sockaddr *)&sockname_temp, &sockname_len)) { + port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp); if (port > 0) { allocated_addr = malloc(addr_len); memcpy(allocated_addr, addr, addr_len); @@ -330,7 +334,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr, if (grpc_sockaddr_is_wildcard(addr, &port)) { grpc_sockaddr_make_wildcard6(port, &wildcard); - addr = (struct sockaddr *) &wildcard; + addr = (struct sockaddr *)&wildcard; addr_len = sizeof(wildcard); } @@ -369,4 +373,4 @@ void grpc_tcp_server_start(grpc_tcp_server *s, grpc_pollset **pollset, gpr_mu_unlock(&s->mu); } -#endif /* GPR_WINSOCK_SOCKET */ +#endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index c155b80b7e..081272724c 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -85,10 +85,10 @@ static void on_secure_transport_setup_done(void *statep, if (status == GRPC_SECURITY_OK) { gpr_mu_lock(&state->mu); if (!state->is_shutdown) { - grpc_create_chttp2_transport( - setup_transport, state->server, - grpc_server_get_channel_args(state->server), - secure_endpoint, NULL, 0, grpc_mdctx_create(), 0); + grpc_create_chttp2_transport(setup_transport, state->server, + grpc_server_get_channel_args(state->server), + secure_endpoint, NULL, 0, + grpc_mdctx_create(), 0); } else { /* We need to consume this here, because the server may already have gone * away. */ @@ -104,7 +104,8 @@ static void on_secure_transport_setup_done(void *statep, static void on_accept(void *statep, grpc_endpoint *tcp) { grpc_server_secure_state *state = statep; state_ref(state); - grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state); + grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, + state); } /* Server callback: start listening on our ports */ @@ -120,12 +121,14 @@ static void destroy(grpc_server *server, void *statep) { grpc_server_secure_state *state = statep; gpr_mu_lock(&state->mu); state->is_shutdown = 1; - grpc_tcp_server_destroy(state->tcp); + grpc_tcp_server_destroy(state->tcp, grpc_server_listener_destroy_done, + server); gpr_mu_unlock(&state->mu); state_unref(state); } -int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) { +int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, + grpc_server_credentials *creds) { grpc_resolved_addresses *resolved = NULL; grpc_tcp_server *tcp = NULL; grpc_server_secure_state *state = NULL; @@ -213,7 +216,7 @@ error: grpc_resolved_addresses_destroy(resolved); } if (tcp) { - grpc_tcp_server_destroy(tcp); + grpc_tcp_server_destroy(tcp, NULL, NULL); } if (state) { gpr_free(state); diff --git a/src/core/support/thd.c b/src/core/support/thd.c new file mode 100644 index 0000000000..ec308f3119 --- /dev/null +++ b/src/core/support/thd.c @@ -0,0 +1,66 @@ +/* + * + * 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. + * + */ + +/* Posix implementation for gpr threads. */ + +#include <memory.h> + +#include <grpc/support/thd.h> + +enum { + GPR_THD_JOINABLE = 1 +}; + +gpr_thd_options gpr_thd_options_default(void) { + gpr_thd_options options; + memset(&options, 0, sizeof(options)); + return options; +} + +void gpr_thd_options_set_detached(gpr_thd_options *options) { + options->flags &= ~GPR_THD_JOINABLE; +} + +void gpr_thd_options_set_joinable(gpr_thd_options *options) { + options->flags |= GPR_THD_JOINABLE; +} + +int gpr_thd_options_is_detached(const gpr_thd_options *options) { + if (!options) return 1; + return (options->flags & GPR_THD_JOINABLE) == 0; +} + +int gpr_thd_options_is_joinable(const gpr_thd_options *options) { + if (!options) return 0; + return (options->flags & GPR_THD_JOINABLE) == GPR_THD_JOINABLE; +} diff --git a/src/core/support/thd_posix.c b/src/core/support/thd_posix.c index f50ea58335..fa4eb50556 100644 --- a/src/core/support/thd_posix.c +++ b/src/core/support/thd_posix.c @@ -68,7 +68,11 @@ int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, a->arg = arg; GPR_ASSERT(pthread_attr_init(&attr) == 0); - GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); + if (gpr_thd_options_is_detached(options)) { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0); + } else { + GPR_ASSERT(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE) == 0); + } thread_started = (pthread_create(&p, &attr, &thread_body, a) == 0); GPR_ASSERT(pthread_attr_destroy(&attr) == 0); if (!thread_started) { @@ -78,14 +82,12 @@ int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, return thread_started; } -gpr_thd_options gpr_thd_options_default(void) { - gpr_thd_options options; - memset(&options, 0, sizeof(options)); - return options; -} - gpr_thd_id gpr_thd_currentid(void) { return (gpr_thd_id)pthread_self(); } +void gpr_thd_join(gpr_thd_id t) { + pthread_join((pthread_t)t, NULL); +} + #endif /* GPR_POSIX_SYNC */ diff --git a/src/core/support/thd_win32.c b/src/core/support/thd_win32.c index 347cad57e3..3cc798293a 100644 --- a/src/core/support/thd_win32.c +++ b/src/core/support/thd_win32.c @@ -31,7 +31,7 @@ * */ -/* Posix implementation for gpr threads. */ +/* Windows implementation for gpr threads. */ #include <grpc/support/port_platform.h> @@ -40,47 +40,81 @@ #include <windows.h> #include <string.h> #include <grpc/support/alloc.h> +#include <grpc/support/log.h> #include <grpc/support/thd.h> -struct thd_arg { +#if defined(_MSC_VER) +#define thread_local __declspec(thread) +#elif defined(__GNUC__) +#define thread_local __thread +#else +#error "Unknown compiler - please file a bug report" +#endif + +struct thd_info { void (*body)(void *arg); /* body of a thread */ void *arg; /* argument to a thread */ + HANDLE join_event; /* if joinable, the join event */ + int joinable; /* true if not detached */ }; +static thread_local struct thd_info *g_thd_info; + +/* Destroys a thread info */ +static void destroy_thread(struct thd_info *t) { + if (t->joinable) CloseHandle(t->join_event); + gpr_free(t); +} + /* Body of every thread started via gpr_thd_new. */ static DWORD WINAPI thread_body(void *v) { - struct thd_arg a = *(struct thd_arg *)v; - gpr_free(v); - (*a.body)(a.arg); + g_thd_info = (struct thd_info *)v; + g_thd_info->body(g_thd_info->arg); + if (g_thd_info->joinable) { + BOOL ret = SetEvent(g_thd_info->join_event); + GPR_ASSERT(ret); + } else { + destroy_thread(g_thd_info); + } return 0; } int gpr_thd_new(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, const gpr_thd_options *options) { HANDLE handle; - DWORD thread_id; - struct thd_arg *a = gpr_malloc(sizeof(*a)); - a->body = thd_body; - a->arg = arg; + struct thd_info *info = gpr_malloc(sizeof(*info)); + info->body = thd_body; + info->arg = arg; *t = 0; - handle = CreateThread(NULL, 64 * 1024, thread_body, a, 0, &thread_id); + if (gpr_thd_options_is_joinable(options)) { + info->joinable = 1; + info->join_event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (info->join_event == NULL) { + gpr_free(info); + return 0; + } + } else { + info->joinable = 0; + } + handle = CreateThread(NULL, 64 * 1024, thread_body, info, 0, NULL); if (handle == NULL) { - gpr_free(a); + destroy_thread(info); } else { - CloseHandle(handle); /* threads are "detached" */ + *t = (gpr_thd_id)info; + CloseHandle(handle); } - *t = (gpr_thd_id)thread_id; return handle != NULL; } -gpr_thd_options gpr_thd_options_default(void) { - gpr_thd_options options; - memset(&options, 0, sizeof(options)); - return options; +gpr_thd_id gpr_thd_currentid(void) { + return (gpr_thd_id)g_thd_info; } -gpr_thd_id gpr_thd_currentid(void) { - return (gpr_thd_id)GetCurrentThreadId(); +void gpr_thd_join(gpr_thd_id t) { + struct thd_info *info = (struct thd_info *)t; + DWORD ret = WaitForSingleObject(info->join_event, INFINITE); + GPR_ASSERT(ret == WAIT_OBJECT_0); + destroy_thread(info); } #endif /* GPR_WIN32 */ diff --git a/src/core/surface/call.c b/src/core/surface/call.c index cfce943794..dba63058b8 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -1006,6 +1006,8 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops, const grpc_op *op; grpc_ioreq *req; + GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, tag); + if (nops == 0) { grpc_cq_begin_op(call->cq, call, GRPC_OP_COMPLETE); grpc_cq_end_op_complete(call->cq, tag, call, do_nothing, NULL, GRPC_OP_OK); diff --git a/src/core/surface/call.h b/src/core/surface/call.h index cb81cb52c2..06434f87ac 100644 --- a/src/core/surface/call.h +++ b/src/core/surface/call.h @@ -119,4 +119,13 @@ grpc_call_stack *grpc_call_get_call_stack(grpc_call *call); /* Given the top call_element, get the call object. */ grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element); +extern int grpc_trace_batch; + +void grpc_call_log_batch(char *file, int line, gpr_log_severity severity, + grpc_call *call, const grpc_op *ops, size_t nops, + void *tag); + +#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \ + if (grpc_trace_batch) grpc_call_log_batch(sev, call, ops, nops, tag) + #endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */ diff --git a/src/core/surface/call_log_batch.c b/src/core/surface/call_log_batch.c new file mode 100644 index 0000000000..a33583a12d --- /dev/null +++ b/src/core/surface/call_log_batch.c @@ -0,0 +1,121 @@ +/* + * + * 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 "src/core/surface/call.h" + +#include "src/core/support/string.h" +#include <grpc/support/alloc.h> + +int grpc_trace_batch = 0; + +static void add_metadata(gpr_strvec *b, const grpc_metadata *md, size_t count) { + size_t i; + for(i = 0; i < count; i++) { + gpr_strvec_add(b, gpr_strdup("\nkey=")); + gpr_strvec_add(b, gpr_strdup(md[i].key)); + + gpr_strvec_add(b, gpr_strdup(" value=")); + gpr_strvec_add(b, gpr_hexdump(md[i].value, md[i].value_length, + GPR_HEXDUMP_PLAINTEXT)); + } +} + +char *grpc_op_string(const grpc_op *op) { + char *tmp; + char *out; + + gpr_strvec b; + gpr_strvec_init(&b); + + switch (op->op) { + case GRPC_OP_SEND_INITIAL_METADATA: + gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA")); + add_metadata(&b, op->data.send_initial_metadata.metadata, + op->data.send_initial_metadata.count); + break; + case GRPC_OP_SEND_MESSAGE: + gpr_asprintf(&tmp, "SEND_MESSAGE ptr=%p", op->data.send_message); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + gpr_strvec_add(&b, gpr_strdup("SEND_CLOSE_FROM_CLIENT")); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + gpr_asprintf(&tmp, "SEND_STATUS_FROM_SERVER status=%d details=%s", + op->data.send_status_from_server.status, + op->data.send_status_from_server.status_details); + gpr_strvec_add(&b, tmp); + add_metadata(&b, op->data.send_status_from_server.trailing_metadata, + op->data.send_status_from_server.trailing_metadata_count); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + gpr_asprintf(&tmp, "RECV_INITIAL_METADATA ptr=%p", + op->data.recv_initial_metadata); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_RECV_MESSAGE: + gpr_asprintf(&tmp, "RECV_MESSAGE ptr=%p", op->data.recv_message); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + gpr_asprintf(&tmp, + "RECV_STATUS_ON_CLIENT metadata=%p status=%p details=%p", + op->data.recv_status_on_client.trailing_metadata, + op->data.recv_status_on_client.status, + op->data.recv_status_on_client.status_details); + gpr_strvec_add(&b, tmp); + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + gpr_asprintf(&tmp, "RECV_CLOSE_ON_SERVER cancelled=%p", + op->data.recv_close_on_server.cancelled); + gpr_strvec_add(&b, tmp); + } + out = gpr_strvec_flatten(&b, NULL); + gpr_strvec_destroy(&b); + + return out; +} + +void grpc_call_log_batch(char *file, int line, gpr_log_severity severity, + grpc_call *call, const grpc_op *ops, size_t nops, + void *tag) { + char *tmp; + size_t i; + gpr_log(file, line, severity, + "grpc_call_start_batch(%p, %p, %d, 0x%x)", call, ops, nops, tag); + for(i = 0; i < nops; i++) { + tmp = grpc_op_string(&ops[i]); + gpr_log(file, line, severity, "ops[%d]: %s", i, tmp); + gpr_free(tmp); + } +} diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c index 6a1d83ce5d..24f4a05071 100644 --- a/src/core/surface/completion_queue.c +++ b/src/core/surface/completion_queue.c @@ -432,3 +432,11 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc) { grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) { return &cc->pollset; } + +void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc) { + gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset)); + grpc_pollset_kick(&cc->pollset); + grpc_pollset_work(&cc->pollset, + gpr_time_add(gpr_now(), gpr_time_from_millis(100))); + gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset)); +} diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h index 3054264cad..3a7cc99dda 100644 --- a/src/core/surface/completion_queue.h +++ b/src/core/surface/completion_queue.h @@ -114,4 +114,6 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc); grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc); -#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */ +void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc); + +#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */ diff --git a/src/core/surface/init.c b/src/core/surface/init.c index e48c4202e5..d4f0eb40e8 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -36,6 +36,7 @@ #include "src/core/debug/trace.h" #include "src/core/statistics/census_interface.h" #include "src/core/channel/channel_stack.h" +#include "src/core/surface/call.h" #include "src/core/surface/init.h" #include "src/core/surface/surface_trace.h" #include "src/core/transport/chttp2_transport.h" @@ -57,6 +58,7 @@ void grpc_init(void) { grpc_register_tracer("channel", &grpc_trace_channel); grpc_register_tracer("surface", &grpc_surface_trace); grpc_register_tracer("http", &grpc_http_trace); + grpc_register_tracer("batch", &grpc_trace_batch); grpc_security_pre_init(); grpc_tracer_init("GRPC_TRACE"); grpc_iomgr_init(); @@ -82,4 +84,3 @@ int grpc_is_initialized(void) { gpr_mu_unlock(&g_init_mu); return r; } - diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 424734c54c..17cba9a505 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -137,6 +137,7 @@ struct grpc_server { size_t cq_count; gpr_mu mu; + gpr_cv cv; registered_method *registered_methods; requested_call_array requested_calls; @@ -149,6 +150,7 @@ struct grpc_server { channel_data root_channel_data; listener *listeners; + int listeners_destroyed; gpr_refcount internal_refcount; }; @@ -263,6 +265,7 @@ static void server_unref(grpc_server *server) { if (gpr_unref(&server->internal_refcount)) { grpc_channel_args_destroy(server->channel_args); gpr_mu_destroy(&server->mu); + gpr_cv_destroy(&server->cv); gpr_free(server->channel_filters); requested_call_array_destroy(&server->requested_calls); while ((rm = server->registered_methods) != NULL) { @@ -589,9 +592,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) { } static const grpc_channel_filter server_surface_filter = { - call_op, channel_op, sizeof(call_data), - init_call_elem, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, "server", + call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem, + sizeof(channel_data), init_channel_elem, destroy_channel_elem, "server", }; static void addcq(grpc_server *server, grpc_completion_queue *cq) { @@ -620,6 +622,7 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq, if (cq) addcq(server, cq); gpr_mu_init(&server->mu); + gpr_cv_init(&server->cv); server->unregistered_cq = cq; /* decremented by grpc_server_destroy */ @@ -733,7 +736,8 @@ grpc_transport_setup_result grpc_server_setup_transport( channel = grpc_channel_create_from_filters(filters, num_filters, s->channel_args, mdctx, 0); chand = (channel_data *)grpc_channel_stack_element( - grpc_channel_get_channel_stack(channel), 0)->channel_data; + grpc_channel_get_channel_stack(channel), 0) + ->channel_data; chand->server = s; server_ref(s); chand->channel = channel; @@ -754,7 +758,7 @@ grpc_transport_setup_result grpc_server_setup_transport( method = grpc_mdstr_from_string(mdctx, rm->method); hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash); for (probes = 0; chand->registered_methods[(hash + probes) % slots] - .server_registered_method != NULL; + .server_registered_method != NULL; probes++) ; if (probes > max_probes) max_probes = probes; @@ -781,6 +785,15 @@ grpc_transport_setup_result grpc_server_setup_transport( return result; } +static int num_listeners(grpc_server *server) { + listener *l; + int n = 0; + for (l = server->listeners; l; l = l->next) { + n++; + } + return n; +} + static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag, void *shutdown_tag) { listener *l; @@ -878,11 +891,6 @@ static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag, for (l = server->listeners; l; l = l->next) { l->destroy(server, l->arg); } - while (server->listeners) { - l = server->listeners; - server->listeners = l->next; - gpr_free(l); - } } void grpc_server_shutdown(grpc_server *server) { @@ -893,8 +901,18 @@ void grpc_server_shutdown_and_notify(grpc_server *server, void *tag) { shutdown_internal(server, 1, tag); } +void grpc_server_listener_destroy_done(void *s) { + grpc_server *server = s; + gpr_mu_lock(&server->mu); + server->listeners_destroyed++; + gpr_cv_signal(&server->cv); + gpr_mu_unlock(&server->mu); +} + void grpc_server_destroy(grpc_server *server) { channel_data *c; + listener *l; + size_t i; gpr_mu_lock(&server->mu); if (!server->shutdown) { gpr_mu_unlock(&server->mu); @@ -902,6 +920,23 @@ void grpc_server_destroy(grpc_server *server) { gpr_mu_lock(&server->mu); } + while (server->listeners_destroyed != num_listeners(server)) { + for (i = 0; i < server->cq_count; i++) { + gpr_mu_unlock(&server->mu); + grpc_cq_hack_spin_pollset(server->cqs[i]); + gpr_mu_lock(&server->mu); + } + + gpr_cv_wait(&server->cv, &server->mu, + gpr_time_add(gpr_now(), gpr_time_from_millis(100))); + } + + while (server->listeners) { + l = server->listeners; + server->listeners = l->next; + gpr_free(l); + } + for (c = server->root_channel_data.next; c != &server->root_channel_data; c = c->next) { shutdown_channel(c); diff --git a/src/core/surface/server.h b/src/core/surface/server.h index e33f69b8c7..2cfa38fa43 100644 --- a/src/core/surface/server.h +++ b/src/core/surface/server.h @@ -48,9 +48,12 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq, and when it shuts down, it will call destroy */ void grpc_server_add_listener(grpc_server *server, void *listener, void (*start)(grpc_server *server, void *arg, - grpc_pollset **pollsets, size_t npollsets), + grpc_pollset **pollsets, + size_t npollsets), void (*destroy)(grpc_server *server, void *arg)); +void grpc_server_listener_destroy_done(void *server); + /* Setup a transport - creates a channel stack, binds the transport to the server */ grpc_transport_setup_result grpc_server_setup_transport( @@ -60,4 +63,4 @@ grpc_transport_setup_result grpc_server_setup_transport( const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server); -#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */ +#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */ diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c index 27434b39e2..f3b9219f8b 100644 --- a/src/core/surface/server_chttp2.c +++ b/src/core/surface/server_chttp2.c @@ -66,7 +66,8 @@ static void new_transport(void *server, grpc_endpoint *tcp) { } /* Server callback: start listening on our ports */ -static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) { +static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, + size_t pollset_count) { grpc_tcp_server *tcp = tcpp; grpc_tcp_server_start(tcp, pollsets, pollset_count, new_transport, server); } @@ -75,7 +76,7 @@ static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size callbacks) */ static void destroy(grpc_server *server, void *tcpp) { grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_destroy(tcp); + grpc_tcp_server_destroy(tcp, grpc_server_listener_destroy_done, server); } int grpc_server_add_http2_port(grpc_server *server, const char *addr) { @@ -131,7 +132,7 @@ error: grpc_resolved_addresses_destroy(resolved); } if (tcp) { - grpc_tcp_server_destroy(tcp); + grpc_tcp_server_destroy(tcp, NULL, NULL); } return 0; } diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 2b15b2a812..4c0394d46f 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -1710,6 +1710,8 @@ static int process_read(transport *t, gpr_slice slice) { gpr_log(GPR_ERROR, "should never reach here"); abort(); + + return 0; } /* tcp read callback */ diff --git a/src/core/transport/metadata.c b/src/core/transport/metadata.c index 1c15716fad..066cc263a1 100644 --- a/src/core/transport/metadata.c +++ b/src/core/transport/metadata.c @@ -97,7 +97,7 @@ static void internal_string_ref(internal_string *s); static void internal_string_unref(internal_string *s); static void discard_metadata(grpc_mdctx *ctx); static void gc_mdtab(grpc_mdctx *ctx); -static void metadata_context_destroy(grpc_mdctx *ctx); +static void metadata_context_destroy_locked(grpc_mdctx *ctx); static void lock(grpc_mdctx *ctx) { gpr_mu_lock(&ctx->mu); } @@ -122,8 +122,7 @@ static void unlock(grpc_mdctx *ctx) { discard_metadata(ctx); } if (ctx->strtab_count == 0) { - gpr_mu_unlock(&ctx->mu); - metadata_context_destroy(ctx); + metadata_context_destroy_locked(ctx); return; } } @@ -185,8 +184,7 @@ static void discard_metadata(grpc_mdctx *ctx) { } } -static void metadata_context_destroy(grpc_mdctx *ctx) { - gpr_mu_lock(&ctx->mu); +static void metadata_context_destroy_locked(grpc_mdctx *ctx) { GPR_ASSERT(ctx->strtab_count == 0); GPR_ASSERT(ctx->mdtab_count == 0); GPR_ASSERT(ctx->mdtab_free == 0); diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index 33645ca8b8..018ddc4456 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -567,7 +567,8 @@ static tsi_result populate_ssl_context( EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) { gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key."); - result = TSI_INTERNAL_ERROR; + EC_KEY_free(ecdh); + return TSI_INTERNAL_ERROR; } SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE); EC_KEY_free(ecdh); @@ -604,6 +605,7 @@ static tsi_result build_alpn_protocol_name_list( unsigned char* current; *protocol_name_list = NULL; *protocol_name_list_length = 0; + if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT; for (i = 0; i < num_alpn_protocols; i++) { if (alpn_protocols_lengths[i] == 0) { gpr_log(GPR_ERROR, "Invalid 0-length protocol name."); diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc new file mode 100644 index 0000000000..3bf7bdf45f --- /dev/null +++ b/src/cpp/client/generic_stub.cc @@ -0,0 +1,51 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <grpc++/generic_stub.h> + +#include <grpc++/impl/rpc_method.h> + +namespace grpc { + +// begin a call to a named method +std::unique_ptr<GenericClientAsyncReaderWriter> GenericStub::Call( + ClientContext* context, const grpc::string& method, + CompletionQueue* cq, void* tag) { + return std::unique_ptr<GenericClientAsyncReaderWriter>( + new GenericClientAsyncReaderWriter( + channel_.get(), cq, RpcMethod(method.c_str()), context, tag)); +} + + +} // namespace grpc + diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index f3ca430bd4..8945b038de 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -31,8 +31,6 @@ * */ -#include <string> - #include <grpc/grpc.h> #include <grpc/support/log.h> diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index e3c6637623..0a73b2c0f6 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -31,40 +31,23 @@ * */ -#include <string> - -#include <grpc/grpc_security.h> #include <grpc/support/log.h> #include <grpc++/channel_arguments.h> -#include <grpc++/config.h> -#include <grpc++/credentials.h> #include "src/cpp/client/channel.h" +#include "src/cpp/client/secure_credentials.h" namespace grpc { -class SecureCredentials GRPC_FINAL : public Credentials { - public: - explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} - ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); } - grpc_credentials* GetRawCreds() { return c_creds_; } - - std::shared_ptr<grpc::ChannelInterface> CreateChannel( - const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE { - grpc_channel_args channel_args; - args.SetChannelArgs(&channel_args); - return std::shared_ptr<ChannelInterface>(new Channel( - args.GetSslTargetNameOverride().empty() - ? target - : args.GetSslTargetNameOverride(), - grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); - } - - SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; } - - private: - grpc_credentials* const c_creds_; -}; +std::shared_ptr<grpc::ChannelInterface> SecureCredentials::CreateChannel( + const string& target, const grpc::ChannelArguments& args) { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return std::shared_ptr<ChannelInterface>(new Channel( + args.GetSslTargetNameOverride().empty() ? target + : args.GetSslTargetNameOverride(), + grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); +} namespace { std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) { diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h new file mode 100644 index 0000000000..77d575813e --- /dev/null +++ b/src/cpp/client/secure_credentials.h @@ -0,0 +1,61 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H +#define GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H + +#include <grpc/grpc_security.h> + +#include <grpc++/config.h> +#include <grpc++/credentials.h> + +namespace grpc { + +class SecureCredentials GRPC_FINAL : public Credentials { + public: + explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} + ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); } + grpc_credentials* GetRawCreds() { return c_creds_; } + + std::shared_ptr<grpc::ChannelInterface> CreateChannel( + const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE; + SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; } + + private: + grpc_credentials* const c_creds_; +}; + +} // namespace grpc + +#endif // GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H + diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc index 5c26a1ad7c..e75e77e0b5 100644 --- a/src/cpp/common/call.cc +++ b/src/cpp/common/call.cc @@ -60,7 +60,8 @@ CallOpBuffer::CallOpBuffer() status_code_(GRPC_STATUS_OK), status_details_(nullptr), status_details_capacity_(0), - send_status_(nullptr), + send_status_available_(false), + send_status_code_(GRPC_STATUS_OK), trailing_metadata_count_(0), trailing_metadata_(nullptr), cancelled_buf_(0), @@ -104,7 +105,9 @@ void CallOpBuffer::Reset(void* next_return_tag) { status_code_ = GRPC_STATUS_OK; - send_status_ = nullptr; + send_status_available_ = false; + send_status_code_ = GRPC_STATUS_OK; + send_status_details_.clear(); trailing_metadata_count_ = 0; trailing_metadata_ = nullptr; @@ -148,7 +151,7 @@ void FillMetadataMap(grpc_metadata_array* arr, // TODO(yangg) handle duplicates? metadata->insert(std::pair<grpc::string, grpc::string>( arr->metadata[i].key, - {arr->metadata[i].value, arr->metadata[i].value_length})); + grpc::string(arr->metadata[i].value, arr->metadata[i].value_length))); } grpc_metadata_array_destroy(arr); grpc_metadata_array_init(arr); @@ -186,6 +189,7 @@ void CallOpBuffer::AddRecvMessage(grpc::protobuf::Message* message) { void CallOpBuffer::AddRecvMessage(ByteBuffer* message) { recv_message_buffer_ = message; + recv_message_buffer_->Clear(); } void CallOpBuffer::AddClientSendClose() { client_send_close_ = true; } @@ -207,7 +211,9 @@ void CallOpBuffer::AddServerSendStatus( } else { trailing_metadata_count_ = 0; } - send_status_ = &status; + send_status_available_ = true; + send_status_code_ = static_cast<grpc_status_code>(status.code()); + send_status_details_ = status.details(); } void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) { @@ -256,16 +262,15 @@ void CallOpBuffer::FillOps(grpc_op* ops, size_t* nops) { &status_details_capacity_; (*nops)++; } - if (send_status_) { + if (send_status_available_) { ops[*nops].op = GRPC_OP_SEND_STATUS_FROM_SERVER; ops[*nops].data.send_status_from_server.trailing_metadata_count = trailing_metadata_count_; ops[*nops].data.send_status_from_server.trailing_metadata = trailing_metadata_; - ops[*nops].data.send_status_from_server.status = - static_cast<grpc_status_code>(send_status_->code()); + ops[*nops].data.send_status_from_server.status = send_status_code_; ops[*nops].data.send_status_from_server.status_details = - send_status_->details().c_str(); + send_status_details_.empty() ? nullptr : send_status_details_.c_str(); (*nops)++; } if (recv_closed_) { diff --git a/src/cpp/common/completion_queue.cc b/src/cpp/common/completion_queue.cc index fede2da016..cea2d24831 100644 --- a/src/cpp/common/completion_queue.cc +++ b/src/cpp/common/completion_queue.cc @@ -36,7 +36,6 @@ #include <grpc/grpc.h> #include <grpc/support/log.h> -#include <grpc/support/time.h> #include "src/cpp/util/time.h" namespace grpc { @@ -57,15 +56,12 @@ class EventDeleter { } }; -CompletionQueue::NextStatus -CompletionQueue::AsyncNext(void** tag, bool* ok, - std::chrono::system_clock::time_point deadline) { +CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal( + void** tag, bool* ok, gpr_timespec deadline) { std::unique_ptr<grpc_event, EventDeleter> ev; - gpr_timespec gpr_deadline; - Timepoint2Timespec(deadline, &gpr_deadline); for (;;) { - ev.reset(grpc_completion_queue_next(cq_, gpr_deadline)); + ev.reset(grpc_completion_queue_next(cq_, deadline)); if (!ev) { /* got a NULL back because deadline passed */ return TIMEOUT; } @@ -81,6 +77,13 @@ CompletionQueue::AsyncNext(void** tag, bool* ok, } } +CompletionQueue::NextStatus CompletionQueue::AsyncNext( + void** tag, bool* ok, std::chrono::system_clock::time_point deadline) { + gpr_timespec gpr_deadline; + Timepoint2Timespec(deadline, &gpr_deadline); + return AsyncNextInternal(tag, ok, gpr_deadline); +} + bool CompletionQueue::Pluck(CompletionQueueTag* tag) { std::unique_ptr<grpc_event, EventDeleter> ev; diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index 88f7a9b1a9..3e262dd74f 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -31,37 +31,23 @@ * */ -#include <grpc/grpc_security.h> - -#include <grpc++/server_credentials.h> +#include "src/cpp/server/secure_server_credentials.h" namespace grpc { -namespace { -class SecureServerCredentials GRPC_FINAL : public ServerCredentials { - public: - explicit SecureServerCredentials(grpc_server_credentials* creds) - : creds_(creds) {} - ~SecureServerCredentials() GRPC_OVERRIDE { - grpc_server_credentials_release(creds_); - } - - int AddPortToServer(const grpc::string& addr, - grpc_server* server) GRPC_OVERRIDE { - return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); - } - - private: - grpc_server_credentials* const creds_; -}; -} // namespace +int SecureServerCredentials::AddPortToServer( + const grpc::string& addr, grpc_server* server) { + return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); +} std::shared_ptr<ServerCredentials> SslServerCredentials( const SslServerCredentialsOptions& options) { std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs; - for (const auto& key_cert_pair : options.pem_key_cert_pairs) { - pem_key_cert_pairs.push_back( - {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()}); + for (auto key_cert_pair = options.pem_key_cert_pairs.begin(); + key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) { + grpc_ssl_pem_key_cert_pair p = {key_cert_pair->private_key.c_str(), + key_cert_pair->cert_chain.c_str()}; + pem_key_cert_pairs.push_back(p); } grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create( options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h new file mode 100644 index 0000000000..b9803f107e --- /dev/null +++ b/src/cpp/server/secure_server_credentials.h @@ -0,0 +1,60 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H +#define GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H + +#include <grpc/grpc_security.h> + +#include <grpc++/server_credentials.h> + +namespace grpc { + +class SecureServerCredentials GRPC_FINAL : public ServerCredentials { + public: + explicit SecureServerCredentials(grpc_server_credentials* creds) + : creds_(creds) {} + ~SecureServerCredentials() GRPC_OVERRIDE { + grpc_server_credentials_release(creds_); + } + + int AddPortToServer(const grpc::string& addr, + grpc_server* server) GRPC_OVERRIDE; + + private: + grpc_server_credentials* const creds_; +}; + +} // namespace grpc + +#endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 5a4ca6915a..046133c5eb 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -107,6 +107,7 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { request_payload_(mrd->request_payload_), method_(mrd->method_) { ctx_.call_ = mrd->call_; + ctx_.cq_ = &cq_; GPR_ASSERT(mrd->in_flight_); mrd->in_flight_ = false; mrd->request_metadata_.count = 0; @@ -182,7 +183,7 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned) Server::~Server() { { - std::unique_lock<std::mutex> lock(mu_); + grpc::unique_lock<grpc::mutex> lock(mu_); if (started_ && !shutdown_) { lock.unlock(); Shutdown(); @@ -247,8 +248,8 @@ bool Server::Start() { // Start processing rpcs. if (!sync_methods_.empty()) { - for (auto& m : sync_methods_) { - m.Request(server_); + for (auto m = sync_methods_.begin(); m != sync_methods_.end(); m++) { + m->Request(server_); } ScheduleCallback(); @@ -258,7 +259,7 @@ bool Server::Start() { } void Server::Shutdown() { - std::unique_lock<std::mutex> lock(mu_); + grpc::unique_lock<grpc::mutex> lock(mu_); if (started_ && !shutdown_) { shutdown_ = true; grpc_server_shutdown(server_); @@ -272,7 +273,7 @@ void Server::Shutdown() { } void Server::Wait() { - std::unique_lock<std::mutex> lock(mu_); + grpc::unique_lock<grpc::mutex> lock(mu_); while (num_running_cb_ != 0) { callback_cv_.wait(lock); } @@ -364,6 +365,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { } } ctx->call_ = call_; + ctx->cq_ = cq_; Call call(call_, server_, cq_); if (orig_status && call_) { ctx->BeginCompletionOp(&call); @@ -403,7 +405,7 @@ void Server::RequestAsyncGenericCall(GenericServerContext* context, void Server::ScheduleCallback() { { - std::unique_lock<std::mutex> lock(mu_); + grpc::unique_lock<grpc::mutex> lock(mu_); num_running_cb_++; } thread_pool_->ScheduleCallback(std::bind(&Server::RunRpc, this)); @@ -424,7 +426,7 @@ void Server::RunRpc() { } { - std::unique_lock<std::mutex> lock(mu_); + grpc::unique_lock<grpc::mutex> lock(mu_); num_running_cb_--; if (shutdown_) { callback_cv_.notify_all(); diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 58bf9d937f..c5e115f396 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -86,24 +86,26 @@ std::unique_ptr<Server> ServerBuilder::BuildAndStart() { thread_pool_owned = true; } std::unique_ptr<Server> server(new Server(thread_pool_, thread_pool_owned)); - for (auto* service : services_) { - if (!server->RegisterService(service)) { + for (auto service = services_.begin(); service != services_.end(); + service++) { + if (!server->RegisterService(*service)) { return nullptr; } } - for (auto* service : async_services_) { - if (!server->RegisterAsyncService(service)) { + for (auto service = async_services_.begin(); + service != async_services_.end(); service++) { + if (!server->RegisterAsyncService(*service)) { return nullptr; } } if (generic_service_) { server->RegisterAsyncGenericService(generic_service_); } - for (auto& port : ports_) { - int r = server->AddListeningPort(port.addr, port.creds.get()); + for (auto port = ports_.begin(); port != ports_.end(); port++) { + int r = server->AddListeningPort(port->addr, port->creds.get()); if (!r) return nullptr; - if (port.selected_port != nullptr) { - *port.selected_port = r; + if (port->selected_port != nullptr) { + *port->selected_port = r; } } if (!server->Start()) { diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index bb3c2d1405..ffd6d30d5d 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -33,9 +33,8 @@ #include <grpc++/server_context.h> -#include <mutex> - #include <grpc++/impl/call.h> +#include <grpc++/impl/sync.h> #include <grpc/grpc.h> #include <grpc/support/log.h> #include "src/cpp/util/time.h" @@ -57,14 +56,14 @@ class ServerContext::CompletionOp GRPC_FINAL : public CallOpBuffer { void Unref(); private: - std::mutex mu_; + grpc::mutex mu_; int refs_; bool finalized_; bool cancelled_; }; void ServerContext::CompletionOp::Unref() { - std::unique_lock<std::mutex> lock(mu_); + grpc::unique_lock<grpc::mutex> lock(mu_); if (--refs_ == 0) { lock.unlock(); delete this; @@ -73,13 +72,13 @@ void ServerContext::CompletionOp::Unref() { bool ServerContext::CompletionOp::CheckCancelled(CompletionQueue* cq) { cq->TryPluck(this); - std::lock_guard<std::mutex> g(mu_); + grpc::lock_guard<grpc::mutex> g(mu_); return finalized_ ? cancelled_ : false; } bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { GPR_ASSERT(CallOpBuffer::FinalizeResult(tag, status)); - std::unique_lock<std::mutex> lock(mu_); + grpc::unique_lock<grpc::mutex> lock(mu_); finalized_ = true; if (!*status) cancelled_ = true; if (--refs_ == 0) { diff --git a/src/cpp/server/thread_pool.cc b/src/cpp/server/thread_pool.cc index d3013b806c..e8d0e89ed2 100644 --- a/src/cpp/server/thread_pool.cc +++ b/src/cpp/server/thread_pool.cc @@ -31,48 +31,52 @@ * */ +#include <grpc++/impl/sync.h> +#include <grpc++/impl/thd.h> + #include "src/cpp/server/thread_pool.h" namespace grpc { +void ThreadPool::ThreadFunc() { + for (;;) { + // Wait until work is available or we are shutting down. + grpc::unique_lock<grpc::mutex> lock(mu_); + if (!shutdown_ && callbacks_.empty()) { + cv_.wait(lock); + } + // 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_) { + return; + } + } +} + ThreadPool::ThreadPool(int num_threads) : shutdown_(false) { for (int i = 0; i < num_threads; i++) { - threads_.push_back(std::thread([this]() { - for (;;) { - // Wait until work is available or we are shutting down. - auto have_work = [this]() { return shutdown_ || !callbacks_.empty(); }; - std::unique_lock<std::mutex> lock(mu_); - if (!have_work()) { - cv_.wait(lock, have_work); - } - // 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_) { - return; - } - } - })); + threads_.push_back(grpc::thread(&ThreadPool::ThreadFunc, this)); } } ThreadPool::~ThreadPool() { { - std::lock_guard<std::mutex> lock(mu_); + grpc::lock_guard<grpc::mutex> lock(mu_); shutdown_ = true; cv_.notify_all(); } - for (auto& t : threads_) { - t.join(); + for (auto t = threads_.begin(); t != threads_.end(); t++) { + t->join(); } } void ThreadPool::ScheduleCallback(const std::function<void()>& callback) { - std::lock_guard<std::mutex> lock(mu_); + grpc::lock_guard<grpc::mutex> lock(mu_); callbacks_.push(callback); cv_.notify_one(); } diff --git a/src/cpp/server/thread_pool.h b/src/cpp/server/thread_pool.h index 6225d82a0b..0f24d6e9b3 100644 --- a/src/cpp/server/thread_pool.h +++ b/src/cpp/server/thread_pool.h @@ -35,11 +35,11 @@ #define GRPC_INTERNAL_CPP_SERVER_THREAD_POOL_H #include <grpc++/config.h> + +#include <grpc++/impl/sync.h> +#include <grpc++/impl/thd.h> #include <grpc++/thread_pool_interface.h> -#include <condition_variable> -#include <thread> -#include <mutex> #include <queue> #include <vector> @@ -53,11 +53,13 @@ class ThreadPool GRPC_FINAL : public ThreadPoolInterface { void ScheduleCallback(const std::function<void()>& callback) GRPC_OVERRIDE; private: - std::mutex mu_; - std::condition_variable cv_; + grpc::mutex mu_; + grpc::condition_variable cv_; bool shutdown_; std::queue<std::function<void()>> callbacks_; - std::vector<std::thread> threads_; + std::vector<grpc::thread> threads_; + + void ThreadFunc(); }; } // namespace grpc diff --git a/src/cpp/util/time.cc b/src/cpp/util/time.cc index 44d2283e76..059ea72abf 100644 --- a/src/cpp/util/time.cc +++ b/src/cpp/util/time.cc @@ -42,11 +42,15 @@ using std::chrono::system_clock; namespace grpc { -// TODO(yangg) prevent potential overflow. void Timepoint2Timespec(const system_clock::time_point& from, gpr_timespec* to) { system_clock::duration deadline = from.time_since_epoch(); seconds secs = duration_cast<seconds>(deadline); + if (from == system_clock::time_point::max() || + secs.count() >= gpr_inf_future.tv_sec || secs.count() < 0) { + *to = gpr_inf_future; + return; + } nanoseconds nsecs = duration_cast<nanoseconds>(deadline - secs); to->tv_sec = secs.count(); to->tv_nsec = nsecs.count(); diff --git a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs index e4328806ad..e0f0474245 100644 --- a/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Core.Tests/Properties/AssemblyInfo.cs @@ -9,4 +9,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec index af8a8869ca..f2032522c9 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.nuspec +++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec @@ -7,7 +7,7 @@ <description>Core C# implementation of gRPC - an RPC library and framework. See project site for more info. This is an experimental release, not ready to use. </description> - <version>0.1.0</version> + <version>0.2.0</version> <authors>Google Inc.</authors> <owners>jtattermusch</owners> <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl> diff --git a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs index 168939cf8c..81218cb67e 100644 --- a/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Core/Properties/AssemblyInfo.cs @@ -9,6 +9,6 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] [assembly: InternalsVisibleTo("Grpc.Core.Tests")] diff --git a/src/csharp/Grpc.Examples.MathClient/MathClient.cs b/src/csharp/Grpc.Examples.MathClient/MathClient.cs index f5956bd33e..ca7683d399 100644 --- a/src/csharp/Grpc.Examples.MathClient/MathClient.cs +++ b/src/csharp/Grpc.Examples.MathClient/MathClient.cs @@ -46,11 +46,15 @@ namespace math MathGrpc.IMathServiceClient stub = new MathGrpc.MathServiceClientStub(channel); MathExamples.DivExample(stub); - MathExamples.FibExample(stub); + MathExamples.DivAsyncExample(stub).Wait(); - MathExamples.SumExample(stub); + MathExamples.FibExample(stub).Wait(); - MathExamples.DivManyExample(stub); + MathExamples.SumExample(stub).Wait(); + + MathExamples.DivManyExample(stub).Wait(); + + MathExamples.DependendRequestsExample(stub).Wait(); } GrpcEnvironment.Shutdown(); diff --git a/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs index 11fc099a95..1989ca8430 100644 --- a/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Examples.MathClient/Properties/AssemblyInfo.cs @@ -9,4 +9,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] diff --git a/src/csharp/Grpc.Examples.MathServer/.gitignore b/src/csharp/Grpc.Examples.MathServer/.gitignore new file mode 100644 index 0000000000..1746e3269e --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/.gitignore @@ -0,0 +1,2 @@ +bin +obj diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj new file mode 100644 index 0000000000..3f7e6c0768 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<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>10.0.0</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{BF62FE08-373A-43D6-9D73-41CAA38B7011}</ProjectGuid> + <OutputType>Exe</OutputType> + <RootNamespace>Grpc.Examples.MathServer</RootNamespace> + <AssemblyName>Grpc.Examples.MathServer</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug</OutputPath> + <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> + <Optimize>true</Optimize> + <OutputPath>bin\Release</OutputPath> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <Externalconsole>true</Externalconsole> + <PlatformTarget>x86</PlatformTarget> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="MathServer.cs" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <ItemGroup> + <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj"> + <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project> + <Name>Grpc.Core</Name> + </ProjectReference> + <ProjectReference Include="..\Grpc.Examples\Grpc.Examples.csproj"> + <Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project> + <Name>Grpc.Examples</Name> + </ProjectReference> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/csharp/Grpc.Examples.MathServer/MathServer.cs b/src/csharp/Grpc.Examples.MathServer/MathServer.cs new file mode 100644 index 0000000000..884a84d0a6 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/MathServer.cs @@ -0,0 +1,61 @@ +#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; +using Grpc.Core; + +namespace math +{ + class MainClass + { + public static void Main(string[] args) + { + String host = "0.0.0.0"; + + GrpcEnvironment.Initialize(); + + Server server = new Server(); + server.AddServiceDefinition(MathGrpc.BindService(new MathServiceImpl())); + int port = server.AddListeningPort(host + ":0"); + server.Start(); + + Console.WriteLine("MathServer listening on port " + port); + + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + } +} diff --git a/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..6b3d0516b9 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/Properties/AssemblyInfo.cs @@ -0,0 +1,12 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("Grpc.Examples.MathServer")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Google Inc. All rights reserved.")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: AssemblyVersion("0.1.*")] diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index cf5a640079..f9c1caf700 100644 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -37,6 +37,18 @@ <Reference Include="Google.ProtocolBuffers"> <HintPath>..\packages\Google.ProtocolBuffers.2.4.1.521\lib\net40\Google.ProtocolBuffers.dll</HintPath> </Reference> + <Reference Include="System.Reactive.Interfaces"> + <HintPath>..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Core"> + <HintPath>..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.Linq"> + <HintPath>..\packages\Rx-Linq.2.2.5\lib\net45\System.Reactive.Linq.dll</HintPath> + </Reference> + <Reference Include="System.Reactive.PlatformServices"> + <HintPath>..\packages\Rx-PlatformServices.2.2.5\lib\net45\System.Reactive.PlatformServices.dll</HintPath> + </Reference> </ItemGroup> <ItemGroup> <Compile Include="Properties\AssemblyInfo.cs" /> diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs index 85f213cb39..fa5d6688a6 100644 --- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs +++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs @@ -33,6 +33,7 @@ using System; using System.Collections.Generic; +using System.Reactive.Linq; using System.Threading; using System.Threading.Tasks; using Grpc.Core; @@ -120,14 +121,12 @@ namespace math.Tests [Test] public void Sum() { - var res = client.Sum(); - foreach (var num in new long[] { 10, 20, 30 }) - { - res.Inputs.OnNext(Num.CreateBuilder().SetNum_(num).Build()); - } - res.Inputs.OnCompleted(); + var clientStreamingResult = client.Sum(); + var numList = new List<long> { 10, 20, 30 }.ConvertAll( + n => Num.CreateBuilder().SetNum_(n).Build()); + numList.Subscribe(clientStreamingResult.Inputs); - Assert.AreEqual(60, res.Task.Result.Num_); + Assert.AreEqual(60, clientStreamingResult.Task.Result.Num_); } [Test] @@ -142,13 +141,7 @@ namespace math.Tests var recorder = new RecordingObserver<DivReply>(); var requestObserver = client.DivMany(recorder); - - foreach (var arg in divArgsList) - { - requestObserver.OnNext(arg); - } - requestObserver.OnCompleted(); - + divArgsList.Subscribe(requestObserver); var result = recorder.ToList().Result; CollectionAssert.AreEqual(new long[] { 3, 4, 3 }, result.ConvertAll((divReply) => divReply.Quotient)); diff --git a/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs index 43c7616ac3..d78e9210c0 100644 --- a/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Examples.Tests/Properties/AssemblyInfo.cs @@ -9,4 +9,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config index 51c17bcd5e..06c5e6a4eb 100644 --- a/src/csharp/Grpc.Examples.Tests/packages.config +++ b/src/csharp/Grpc.Examples.Tests/packages.config @@ -1,5 +1,10 @@ -<?xml version="1.0" encoding="utf-8"?> -<packages> - <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" /> - <package id="NUnit" version="2.6.4" targetFramework="net45" /> +<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.ProtocolBuffers" version="2.4.1.521" targetFramework="net45" />
+ <package id="NUnit" version="2.6.4" targetFramework="net45" />
+ <package id="Rx-Core" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-Interfaces" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-Linq" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-Main" version="2.2.5" targetFramework="net45" />
+ <package id="Rx-PlatformServices" version="2.2.5" targetFramework="net45" />
</packages>
\ No newline at end of file diff --git a/src/csharp/Grpc.Examples/MathExamples.cs b/src/csharp/Grpc.Examples/MathExamples.cs index b8bb7eacbd..032372b2a1 100644 --- a/src/csharp/Grpc.Examples/MathExamples.cs +++ b/src/csharp/Grpc.Examples/MathExamples.cs @@ -45,51 +45,45 @@ namespace math Console.WriteLine("Div Result: " + result); } - public static void DivAsyncExample(MathGrpc.IMathServiceClient stub) + public static async Task DivAsyncExample(MathGrpc.IMathServiceClient stub) { - Task<DivReply> call = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build()); - DivReply result = call.Result; - Console.WriteLine(result); + Task<DivReply> resultTask = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build()); + DivReply result = await resultTask; + Console.WriteLine("DivAsync Result: " + result); } - public static void DivAsyncWithCancellationExample(MathGrpc.IMathServiceClient stub) + public static async Task DivAsyncWithCancellationExample(MathGrpc.IMathServiceClient stub) { - Task<DivReply> call = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build()); - DivReply result = call.Result; + Task<DivReply> resultTask = stub.DivAsync(new DivArgs.Builder { Dividend = 4, Divisor = 5 }.Build()); + DivReply result = await resultTask; Console.WriteLine(result); } - public static void FibExample(MathGrpc.IMathServiceClient stub) + public static async Task FibExample(MathGrpc.IMathServiceClient stub) { var recorder = new RecordingObserver<Num>(); stub.Fib(new FibArgs.Builder { Limit = 5 }.Build(), recorder); - - List<Num> numbers = recorder.ToList().Result; - Console.WriteLine("Fib Result: " + string.Join("|", recorder.ToList().Result)); + List<Num> result = await recorder.ToList(); + Console.WriteLine("Fib Result: " + string.Join("|", result)); } - public static void SumExample(MathGrpc.IMathServiceClient stub) + public static async Task SumExample(MathGrpc.IMathServiceClient stub) { - List<Num> numbers = new List<Num> + var numbers = new List<Num> { new Num.Builder { Num_ = 1 }.Build(), new Num.Builder { Num_ = 2 }.Build(), new Num.Builder { Num_ = 3 }.Build() }; - var res = stub.Sum(); - foreach (var num in numbers) - { - res.Inputs.OnNext(num); - } - res.Inputs.OnCompleted(); - - Console.WriteLine("Sum Result: " + res.Task.Result); + var clientStreamingResult = stub.Sum(); + numbers.Subscribe(clientStreamingResult.Inputs); + Console.WriteLine("Sum Result: " + await clientStreamingResult.Task); } - public static void DivManyExample(MathGrpc.IMathServiceClient stub) + public static async Task DivManyExample(MathGrpc.IMathServiceClient stub) { - List<DivArgs> divArgsList = new List<DivArgs> + var divArgsList = new List<DivArgs> { new DivArgs.Builder { Dividend = 10, Divisor = 3 }.Build(), new DivArgs.Builder { Dividend = 100, Divisor = 21 }.Build(), @@ -97,26 +91,27 @@ namespace math }; var recorder = new RecordingObserver<DivReply>(); - var inputs = stub.DivMany(recorder); - foreach (var input in divArgsList) - { - inputs.OnNext(input); - } - inputs.OnCompleted(); - - Console.WriteLine("DivMany Result: " + string.Join("|", recorder.ToList().Result)); + divArgsList.Subscribe(inputs); + var result = await recorder.ToList(); + Console.WriteLine("DivMany Result: " + string.Join("|", result)); } - public static void DependendRequestsExample(MathGrpc.IMathServiceClient stub) + public static async Task DependendRequestsExample(MathGrpc.IMathServiceClient stub) { - var numberList = new List<Num> + var numbers = new List<Num> { - new Num.Builder { Num_ = 1 }.Build(), - new Num.Builder { Num_ = 2 }.Build(), new Num.Builder { Num_ = 3 }.Build() + new Num.Builder { Num_ = 1 }.Build(), + new Num.Builder { Num_ = 2 }.Build(), + new Num.Builder { Num_ = 3 }.Build() }; - numberList.ToObservable(); + var clientStreamingResult = stub.Sum(); + numbers.Subscribe(clientStreamingResult.Inputs); + Num sum = await clientStreamingResult.Task; + + DivReply result = await stub.DivAsync(new DivArgs.Builder { Dividend = sum.Num_, Divisor = numbers.Count }.Build()); + Console.WriteLine("Avg Result: " + result); } } } diff --git a/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs b/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs index b55d24166c..fd1cdbbc1c 100644 --- a/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.Examples/Properties/AssemblyInfo.cs @@ -9,4 +9,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs index c93dd1eb2f..d9d36f03e4 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs @@ -9,4 +9,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs index f3def1aea4..b0b163b883 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs @@ -9,4 +9,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] diff --git a/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs index f09a448e9e..fe6c8a8aed 100644 --- a/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs +++ b/src/csharp/Grpc.IntegrationTesting/Properties/AssemblyInfo.cs @@ -9,4 +9,4 @@ using System.Runtime.CompilerServices; [assembly: AssemblyCopyright("Google Inc. All rights reserved.")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.1.*")] +[assembly: AssemblyVersion("0.2.*")] diff --git a/src/csharp/Grpc.nuspec b/src/csharp/Grpc.nuspec index 96a6aaf6b7..4c106a2ca2 100644 --- a/src/csharp/Grpc.nuspec +++ b/src/csharp/Grpc.nuspec @@ -7,7 +7,7 @@ <description>C# implementation of gRPC - an RPC library and framework. See project site for more info. This is an experimental release, not ready to use. </description> - <version>0.1.0</version> + <version>0.2.0</version> <authors>Google Inc.</authors> <owners>jtattermusch</owners> <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl> @@ -17,7 +17,7 @@ <copyright>Copyright 2015, Google Inc.</copyright> <tags>gRPC RPC Protocol HTTP/2</tags> <dependencies> - <dependency id="Grpc.Core" version="0.1.0" /> + <dependency id="Grpc.Core" version="0.2.0" /> </dependencies> </metadata> </package> diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln index 2e6d288699..2f8c2e1719 100644 --- a/src/csharp/Grpc.sln +++ b/src/csharp/Grpc.sln @@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Cli EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.csproj", "{A654F3B8-E859-4E6A-B30D-227527DBEF0D}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples.MathServer", "Grpc.Examples.MathServer\Grpc.Examples.MathServer.csproj", "{BF62FE08-373A-43D6-9D73-41CAA38B7011}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
@@ -47,6 +49,10 @@ Global {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
+ {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
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 9a1c908d11..e182468d9b 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -731,7 +731,7 @@ grpcsharp_ssl_credentials_create(const char *pem_root_certs, } } -GPR_EXPORT void grpcsharp_credentials_release(grpc_credentials *creds) { +GPR_EXPORT void GPR_CALLTYPE grpcsharp_credentials_release(grpc_credentials *creds) { grpc_credentials_release(creds); } @@ -765,7 +765,7 @@ grpcsharp_ssl_server_credentials_create( return creds; } -GPR_EXPORT void grpcsharp_server_credentials_release( +GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_credentials_release( grpc_server_credentials *creds) { grpc_server_credentials_release(creds); } diff --git a/src/node/binding.gyp b/src/node/binding.gyp index 7ef3bdf4bd..83f72fabca 100644 --- a/src/node/binding.gyp +++ b/src/node/binding.gyp @@ -18,12 +18,29 @@ ], 'link_settings': { 'libraries': [ - '-lrt', '-lpthread', '-lgrpc', '-lgpr' - ], + ] }, + "conditions": [ + ['OS == "mac"', { + 'xcode_settings': { + 'MACOSX_DEPLOYMENT_TARGET': '10.9', + 'OTHER_CFLAGS': [ + '-std=c++11', + '-stdlib=libc++' + ] + } + }], + ['OS != "mac"', { + 'link_settings': { + 'libraries': [ + '-lrt' + ] + } + }] + ], "target_name": "grpc", "sources": [ "ext/byte_buffer.cc", diff --git a/src/node/examples/qps_test.js b/src/node/examples/qps_test.js new file mode 100644 index 0000000000..00293b464a --- /dev/null +++ b/src/node/examples/qps_test.js @@ -0,0 +1,136 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** + * This script runs a QPS test. It sends requests for a specified length of time + * with a specified number pending at any one time. It then outputs the measured + * QPS. Usage: + * node qps_test.js [--concurrent=count] [--time=seconds] + * concurrent defaults to 100 and time defaults to 10 + */ + +'use strict'; + +var async = require('async'); +var parseArgs = require('minimist'); + +var grpc = require('..'); +var testProto = grpc.load(__dirname + '/../interop/test.proto').grpc.testing; +var interop_server = require('../interop/interop_server.js'); + +/** + * Runs the QPS test. Sends requests constantly for the given number of seconds, + * and keeps concurrent_calls requests pending at all times. When the test ends, + * the callback is called with the number of calls that completed within the + * time limit. + * @param {number} concurrent_calls The number of calls to have pending + * simultaneously + * @param {number} seconds The number of seconds to run the test for + * @param {function(Error, number)} callback Callback for test completion + */ +function runTest(concurrent_calls, seconds, callback) { + var testServer = interop_server.getServer(0, false); + testServer.server.listen(); + var client = new testProto.TestService('localhost:' + testServer.port); + + var warmup_num = 100; + + /** + * Warms up the client to avoid counting startup time in the test result + * @param {function(Error)} callback Called when warmup is complete + */ + function warmUp(callback) { + var pending = warmup_num; + function startCall() { + client.emptyCall({}, function(err, resp) { + if (err) { + callback(err); + return; + } + pending--; + if (pending === 0) { + callback(null); + } + }); + } + for (var i = 0; i < warmup_num; i++) { + startCall(); + } + } + /** + * Run the QPS test. Starts concurrent_calls requests, then starts a new + * request whenever one completes until time runs out. + * @param {function(Error, number)} callback Called when the test is complete. + * The second argument is the number of calls that finished within the + * time limit + */ + function run(callback) { + var running = 0; + var count = 0; + var start = process.hrtime(); + function responseCallback(err, resp) { + if (process.hrtime(start)[0] < seconds) { + count += 1; + client.emptyCall({}, responseCallback); + } else { + running -= 1; + if (running <= 0) { + callback(null, count); + } + } + } + for (var i = 0; i < concurrent_calls; i++) { + running += 1; + client.emptyCall({}, responseCallback); + } + } + async.waterfall([warmUp, run], function(err, count) { + testServer.server.shutdown(); + callback(err, count); + }); +} + +if (require.main === module) { + var argv = parseArgs(process.argv.slice(2), { + default: {'concurrent': 100, + 'time': 10} + }); + runTest(argv.concurrent, argv.time, function(err, count) { + if (err) { + throw err; + } + console.log('Concurrent calls:', argv.concurrent); + console.log('Time:', argv.time, 'seconds'); + console.log('QPS:', (count/argv.time)); + }); +} diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc index 82b54b518c..01bd92ea52 100644 --- a/src/node/ext/byte_buffer.cc +++ b/src/node/ext/byte_buffer.cc @@ -32,7 +32,6 @@ */ #include <string.h> -#include <malloc.h> #include <node.h> #include <nan.h> diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc index 787e274973..d37bf763dd 100644 --- a/src/node/ext/channel.cc +++ b/src/node/ext/channel.cc @@ -31,8 +31,6 @@ * */ -#include <malloc.h> - #include <vector> #include <node.h> diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc index e47bac833b..3c2396b810 100644 --- a/src/node/ext/server.cc +++ b/src/node/ext/server.cc @@ -38,8 +38,6 @@ #include <node.h> #include <nan.h> -#include <malloc.h> - #include <vector> #include "grpc/grpc.h" #include "grpc/grpc_security.h" diff --git a/src/node/index.js b/src/node/index.js index ad3dd96af7..0b768edc6b 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -56,7 +56,7 @@ function loadObject(value) { }); return result; } else if (value.className === 'Service') { - return client.makeClientConstructor(value); + return client.makeProtobufClientConstructor(value); } else if (value.className === 'Message' || value.className === 'Enum') { return value.build(); } else { @@ -119,7 +119,7 @@ exports.load = load; /** * See docs for server.makeServerConstructor */ -exports.buildServer = server.makeServerConstructor; +exports.buildServer = server.makeProtobufServerConstructor; /** * Status name to code number mapping @@ -141,3 +141,7 @@ exports.Credentials = grpc.Credentials; exports.ServerCredentials = grpc.ServerCredentials; exports.getGoogleAuthDelegate = getGoogleAuthDelegate; + +exports.makeGenericClientConstructor = client.makeClientConstructor; + +exports.makeGenericServerConstructor = server.makeServerConstructor; diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js index 8060baf827..3341486b9e 100644 --- a/src/node/interop/interop_client.js +++ b/src/node/interop/interop_client.js @@ -35,6 +35,7 @@ var fs = require('fs'); var path = require('path'); +var _ = require('underscore'); var grpc = require('..'); var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; var GoogleAuth = require('google-auth-library'); @@ -45,6 +46,8 @@ var AUTH_SCOPE = 'https://www.googleapis.com/auth/xapi.zoo'; var AUTH_SCOPE_RESPONSE = 'xapi.zoo'; var AUTH_USER = ('155450119199-3psnrh1sdr3d8cpj1v46naggf81mhdnk' + '@developer.gserviceaccount.com'); +var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' + + '@developer.gserviceaccount.com'); /** * Create a buffer filled with size zeroes @@ -265,11 +268,12 @@ function cancelAfterFirstResponse(client, done) { /** * Run one of the authentication tests. + * @param {string} expected_user The expected username in the response * @param {Client} client The client to test against * @param {function} done Callback to call when the test is completed. Included * primarily for use with mocha */ -function authTest(client, done) { +function authTest(expected_user, client, done) { (new GoogleAuth()).getApplicationDefault(function(err, credential) { assert.ifError(err); if (credential.createScopedRequired()) { @@ -290,7 +294,7 @@ function authTest(client, done) { assert.strictEqual(resp.payload.type, testProto.PayloadType.COMPRESSABLE); assert.strictEqual(resp.payload.body.limit - resp.payload.body.offset, 314159); - assert.strictEqual(resp.username, AUTH_USER); + assert.strictEqual(resp.username, expected_user); assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE); }); call.on('status', function(status) { @@ -314,8 +318,8 @@ var test_cases = { empty_stream: emptyStream, cancel_after_begin: cancelAfterBegin, cancel_after_first_response: cancelAfterFirstResponse, - compute_engine_creds: authTest, - service_account_creds: authTest + compute_engine_creds: _.partial(authTest, COMPUTE_ENGINE_USER), + service_account_creds: _.partial(authTest, AUTH_USER) }; /** diff --git a/src/node/src/client.js b/src/node/src/client.js index 54b8dbdc9c..fad369c2f8 100644 --- a/src/node/src/client.js +++ b/src/node/src/client.js @@ -35,9 +35,6 @@ var _ = require('underscore'); -var capitalize = require('underscore.string/capitalize'); -var decapitalize = require('underscore.string/decapitalize'); - var grpc = require('bindings')('grpc.node'); var common = require('./common.js'); @@ -244,13 +241,13 @@ function makeUnaryRequestFunction(method, serialize, deserialize) { callback(err); return; } + emitter.emit('status', response.status); if (response.status.code !== grpc.status.OK) { var error = new Error(response.status.details); error.code = response.status.code; callback(error); return; } - emitter.emit('status', response.status); emitter.emit('metadata', response.metadata); callback(null, deserialize(response.read)); }); @@ -315,13 +312,13 @@ function makeClientStreamRequestFunction(method, serialize, deserialize) { callback(err); return; } + stream.emit('status', response.status); if (response.status.code !== grpc.status.OK) { var error = new Error(response.status.details); error.code = response.status.code; callback(error); return; } - stream.emit('status', response.status); callback(null, deserialize(response.read)); }); }); @@ -463,13 +460,18 @@ var requester_makers = { }; /** - * Creates a constructor for clients for the given service - * @param {ProtoBuf.Reflect.Service} service The service to generate a client - * for + * Creates a constructor for a client with the given methods. The methods object + * maps method name to an object with the following keys: + * path: The path on the server for accessing the method. For example, for + * protocol buffers, we use "/service_name/method_name" + * requestStream: bool indicating whether the client sends a stream + * resonseStream: bool indicating whether the server sends a stream + * requestSerialize: function to serialize request objects + * responseDeserialize: function to deserialize response objects + * @param {Object} methods An object mapping method names to method attributes * @return {function(string, Object)} New client constructor */ -function makeClientConstructor(service) { - var prefix = '/' + common.fullyQualifiedName(service) + '/'; +function makeClientConstructor(methods) { /** * Create a client with the given methods * @constructor @@ -489,30 +491,41 @@ function makeClientConstructor(service) { this.channel = new grpc.Channel(address, options); } - _.each(service.children, function(method) { + _.each(methods, function(attrs, name) { var method_type; - if (method.requestStream) { - if (method.responseStream) { + if (attrs.requestStream) { + if (attrs.responseStream) { method_type = 'bidi'; } else { method_type = 'client_stream'; } } else { - if (method.responseStream) { + if (attrs.responseStream) { method_type = 'server_stream'; } else { method_type = 'unary'; } } - var serialize = common.serializeCls(method.resolvedRequestType.build()); - var deserialize = common.deserializeCls( - method.resolvedResponseType.build()); - Client.prototype[decapitalize(method.name)] = requester_makers[method_type]( - prefix + capitalize(method.name), serialize, deserialize); - Client.prototype[decapitalize(method.name)].serialize = serialize; - Client.prototype[decapitalize(method.name)].deserialize = deserialize; + var serialize = attrs.requestSerialize; + var deserialize = attrs.responseDeserialize; + Client.prototype[name] = requester_makers[method_type]( + attrs.path, serialize, deserialize); + Client.prototype[name].serialize = serialize; + Client.prototype[name].deserialize = deserialize; }); + return Client; +} + +/** + * Creates a constructor for clients for the given service + * @param {ProtoBuf.Reflect.Service} service The service to generate a client + * for + * @return {function(string, Object)} New client constructor + */ +function makeProtobufClientConstructor(service) { + var method_attrs = common.getProtobufServiceAttrs(service); + var Client = makeClientConstructor(method_attrs); Client.service = service; return Client; @@ -520,6 +533,8 @@ function makeClientConstructor(service) { exports.makeClientConstructor = makeClientConstructor; +exports.makeProtobufClientConstructor = makeProtobufClientConstructor; + /** * See docs for client.status */ diff --git a/src/node/src/common.js b/src/node/src/common.js index eec8f0f987..55a6b13782 100644 --- a/src/node/src/common.js +++ b/src/node/src/common.js @@ -36,6 +36,7 @@ var _ = require('underscore'); var capitalize = require('underscore.string/capitalize'); +var decapitalize = require('underscore.string/decapitalize'); /** * Get a function that deserializes a specific type of protobuf. @@ -110,6 +111,26 @@ function wrapIgnoreNull(func) { } /** + * 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) { + var prefix = '/' + fullyQualifiedName(service) + '/'; + return _.object(_.map(service.children, function(method) { + return [decapitalize(method.name), { + path: prefix + capitalize(method.name), + requestStream: method.requestStream, + responseStream: method.responseStream, + requestSerialize: serializeCls(method.resolvedRequestType.build()), + requestDeserialize: deserializeCls(method.resolvedRequestType.build()), + responseSerialize: serializeCls(method.resolvedResponseType.build()), + responseDeserialize: deserializeCls(method.resolvedResponseType.build()) + }]; + })); +} + +/** * See docs for deserializeCls */ exports.deserializeCls = deserializeCls; @@ -128,3 +149,5 @@ 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 b72d110666..05de16294d 100644 --- a/src/node/src/server.js +++ b/src/node/src/server.js @@ -35,9 +35,6 @@ var _ = require('underscore'); -var capitalize = require('underscore.string/capitalize'); -var decapitalize = require('underscore.string/decapitalize'); - var grpc = require('bindings')('grpc.node'); var common = require('./common'); @@ -73,6 +70,9 @@ function handleError(call, error) { status.details = error.details; } } + if (error.hasOwnProperty('metadata')) { + status.metadata = error.metadata; + } var error_batch = {}; error_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status; call.startBatch(error_batch, function(){}); @@ -105,15 +105,20 @@ function waitForCancel(call, emitter) { * @param {*} value The value to respond with * @param {function(*):Buffer=} serialize Serialization function for the * response + * @param {Object=} metadata Optional trailing metadata to send with status */ -function sendUnaryResponse(call, value, serialize) { +function sendUnaryResponse(call, value, serialize, metadata) { var end_batch = {}; - end_batch[grpc.opType.SEND_MESSAGE] = serialize(value); - end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { + var status = { code: grpc.status.OK, details: 'OK', metadata: {} }; + if (metadata) { + status.metadata = metadata; + } + end_batch[grpc.opType.SEND_MESSAGE] = serialize(value); + end_batch[grpc.opType.SEND_STATUS_FROM_SERVER] = status; call.startBatch(end_batch, function (){}); } @@ -146,6 +151,7 @@ function setUpWritable(stream, serialize) { function setStatus(err) { var code = grpc.status.INTERNAL; var details = 'Unknown Error'; + var metadata = {}; if (err.hasOwnProperty('message')) { details = err.message; } @@ -155,7 +161,10 @@ function setUpWritable(stream, serialize) { details = err.details; } } - stream.status = {code: code, details: details, metadata: {}}; + if (err.hasOwnProperty('metadata')) { + metadata = err.metadata; + } + stream.status = {code: code, details: details, metadata: metadata}; } /** * Terminate the call. This includes indicating that reads are done, draining @@ -169,6 +178,17 @@ function setUpWritable(stream, serialize) { stream.end(); } stream.on('error', terminateCall); + /** + * Override of Writable#end method that allows for sending metadata with a + * success status. + * @param {Object=} metadata Metadata to send with the status + */ + stream.end = function(metadata) { + if (metadata) { + stream.status.metadata = metadata; + } + Writable.prototype.end.call(this); + }; } /** @@ -338,11 +358,13 @@ function handleUnary(call, handler, metadata) { if (emitter.cancelled) { return; } - handler.func(emitter, function sendUnaryData(err, value) { + handler.func(emitter, function sendUnaryData(err, value, trailer) { if (err) { + err.metadata = trailer; handleError(call, err); + } else { + sendUnaryResponse(call, value, handler.serialize, trailer); } - sendUnaryResponse(call, value, handler.serialize); }); }); } @@ -381,12 +403,14 @@ function handleClientStreaming(call, handler, metadata) { var metadata_batch = {}; metadata_batch[grpc.opType.SEND_INITIAL_METADATA] = metadata; call.startBatch(metadata_batch, function() {}); - handler.func(stream, function(err, value) { + handler.func(stream, function(err, value, trailer) { stream.terminate(); if (err) { + err.metadata = trailer; handleError(call, err); + } else { + sendUnaryResponse(call, value, handler.serialize, trailer); } - sendUnaryResponse(call, value, handler.serialize); }); } @@ -532,26 +556,20 @@ Server.prototype.bind = function(port, creds) { }; /** - * Creates a constructor for servers with a service defined by the methods - * object. The methods object has string keys and values of this form: - * {serialize: function, deserialize: function, client_stream: bool, - * server_stream: bool} - * @param {Object} methods Method descriptor for each method the server should - * expose - * @param {string} prefix The prefex to prepend to each method name - * @return {function(Object, Object)} New server constructor + * Create a constructor for servers with services defined by service_attr_map. + * That is an object that maps (namespaced) service names to objects that in + * turn map method names to objects with the following keys: + * path: The path on the server for accessing the method. For example, for + * protocol buffers, we use "/service_name/method_name" + * requestStream: bool indicating whether the client sends a stream + * resonseStream: bool indicating whether the server sends a stream + * requestDeserialize: function to deserialize request objects + * responseSerialize: function to serialize response objects + * @param {Object} service_attr_map An object mapping service names to method + * attribute map objects + * @return {function(Object, function, Object=)} New server constructor */ -function makeServerConstructor(services) { - var qual_names = []; - _.each(services, function(service) { - _.each(service.children, function(method) { - var name = common.fullyQualifiedName(method); - if (_.indexOf(qual_names, name) !== -1) { - throw new Error('Method ' + name + ' exposed by more than one service'); - } - qual_names.push(name); - }); - }); +function makeServerConstructor(service_attr_map) { /** * Create a server with the given handlers for all of the methods. * @constructor @@ -565,41 +583,34 @@ function makeServerConstructor(services) { function SurfaceServer(service_handlers, getMetadata, options) { var server = new Server(getMetadata, options); this.inner_server = server; - _.each(services, function(service) { - var service_name = common.fullyQualifiedName(service); + _.each(service_attr_map, function(service_attrs, service_name) { if (service_handlers[service_name] === undefined) { throw new Error('Handlers for service ' + service_name + ' not provided.'); } - var prefix = '/' + common.fullyQualifiedName(service) + '/'; - _.each(service.children, function(method) { + _.each(service_attrs, function(attrs, name) { var method_type; - if (method.requestStream) { - if (method.responseStream) { + if (attrs.requestStream) { + if (attrs.responseStream) { method_type = 'bidi'; } else { method_type = 'client_stream'; } } else { - if (method.responseStream) { + if (attrs.responseStream) { method_type = 'server_stream'; } else { method_type = 'unary'; } } - if (service_handlers[service_name][decapitalize(method.name)] === - undefined) { - throw new Error('Method handler for ' + - common.fullyQualifiedName(method) + ' not provided.'); + if (service_handlers[service_name][name] === undefined) { + throw new Error('Method handler for ' + attrs.path + + ' not provided.'); } - var serialize = common.serializeCls( - method.resolvedResponseType.build()); - var deserialize = common.deserializeCls( - method.resolvedRequestType.build()); - server.register( - prefix + capitalize(method.name), - service_handlers[service_name][decapitalize(method.name)], - serialize, deserialize, method_type); + var serialize = attrs.responseSerialize; + var deserialize = attrs.requestDeserialize; + server.register(attrs.path, service_handlers[service_name][name], + serialize, deserialize, method_type); }); }, this); } @@ -636,6 +647,39 @@ function makeServerConstructor(services) { } /** + * Create a constructor for servers that serve the given services. + * @param {Array<ProtoBuf.Reflect.Service>} services The services that the + * servers will serve + * @return {function(Object, function, Object=)} New server constructor + */ +function makeProtobufServerConstructor(services) { + var qual_names = []; + var service_attr_map = {}; + _.each(services, function(service) { + var service_name = common.fullyQualifiedName(service); + _.each(service.children, function(method) { + var name = common.fullyQualifiedName(method); + if (_.indexOf(qual_names, name) !== -1) { + throw new Error('Method ' + name + ' exposed by more than one service'); + } + qual_names.push(name); + }); + var method_attrs = common.getProtobufServiceAttrs(service); + if (!service_attr_map.hasOwnProperty(service_name)) { + service_attr_map[service_name] = {}; + } + service_attr_map[service_name] = _.extend(service_attr_map[service_name], + method_attrs); + }); + return makeServerConstructor(service_attr_map); +} + +/** * See documentation for makeServerConstructor */ exports.makeServerConstructor = makeServerConstructor; + +/** + * See documentation for makeProtobufServerConstructor + */ +exports.makeProtobufServerConstructor = makeProtobufServerConstructor; diff --git a/src/node/test/surface_test.js b/src/node/test/surface_test.js index 91d8197bee..590c644c71 100644 --- a/src/node/test/surface_test.js +++ b/src/node/test/surface_test.js @@ -45,6 +45,8 @@ var math_proto = ProtoBuf.loadProtoFile(__dirname + '/../examples/math.proto'); var mathService = math_proto.lookup('math.Math'); +var capitalize = require('underscore.string/capitalize'); + describe('Surface server constructor', function() { it('Should fail with conflicting method names', function() { assert.throws(function() { @@ -75,6 +77,216 @@ describe('Surface server constructor', function() { }, /math.Math/); }); }); +describe('Generic client and server', function() { + function toString(val) { + return val.toString(); + } + function toBuffer(str) { + return new Buffer(str); + } + var string_service_attrs = { + 'capitalize' : { + path: '/string/capitalize', + requestStream: false, + responseStream: false, + requestSerialize: toBuffer, + requestDeserialize: toString, + responseSerialize: toBuffer, + responseDeserialize: toString + } + }; + describe('String client and server', function() { + var client; + var server; + before(function() { + var Server = grpc.makeGenericServerConstructor({ + string: string_service_attrs + }); + server = new Server({ + string: { + capitalize: function(call, callback) { + callback(null, capitalize(call.request)); + } + } + }); + var port = server.bind('localhost:0'); + server.listen(); + var Client = grpc.makeGenericClientConstructor(string_service_attrs); + client = new Client('localhost:' + port); + }); + after(function() { + server.shutdown(); + }); + it('Should respond with a capitalized string', function(done) { + client.capitalize('abc', function(err, response) { + assert.ifError(err); + assert.strictEqual(response, 'Abc'); + done(); + }); + }); + }); +}); +describe('Trailing metadata', function() { + var client; + var server; + before(function() { + var test_proto = ProtoBuf.loadProtoFile(__dirname + '/test_service.proto'); + var test_service = test_proto.lookup('TestService'); + var Server = grpc.buildServer([test_service]); + server = new Server({ + TestService: { + unary: function(call, cb) { + var req = call.request; + if (req.error) { + cb(new Error('Requested error'), null, {metadata: ['yes']}); + } else { + cb(null, {count: 1}, {metadata: ['yes']}); + } + }, + clientStream: function(stream, cb){ + var count = 0; + var errored; + stream.on('data', function(data) { + if (data.error) { + errored = true; + cb(new Error('Requested error'), null, {metadata: ['yes']}); + } else { + count += 1; + } + }); + stream.on('end', function() { + if (!errored) { + cb(null, {count: count}, {metadata: ['yes']}); + } + }); + }, + serverStream: function(stream) { + var req = stream.request; + if (req.error) { + var err = new Error('Requested error'); + err.metadata = {metadata: ['yes']}; + stream.emit('error', err); + } else { + for (var i = 0; i < 5; i++) { + stream.write({count: i}); + } + stream.end({metadata: ['yes']}); + } + }, + bidiStream: function(stream) { + var count = 0; + stream.on('data', function(data) { + if (data.error) { + var err = new Error('Requested error'); + err.metadata = { + metadata: ['yes'], + count: ['' + count] + }; + stream.emit('error', err); + } else { + stream.write({count: count}); + count += 1; + } + }); + stream.on('end', function() { + stream.end({metadata: ['yes']}); + }); + } + } + }); + var port = server.bind('localhost:0'); + var Client = surface_client.makeProtobufClientConstructor(test_service); + client = new Client('localhost:' + port); + server.listen(); + }); + after(function() { + server.shutdown(); + }); + it('should be present when a unary call succeeds', function(done) { + var call = client.unary({error: false}, function(err, data) { + assert.ifError(err); + }); + call.on('status', function(status) { + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); + it('should be present when a unary call fails', function(done) { + var call = client.unary({error: true}, function(err, data) { + assert(err); + }); + call.on('status', function(status) { + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); + it('should be present when a client stream call succeeds', function(done) { + var call = client.clientStream(function(err, data) { + assert.ifError(err); + }); + call.write({error: false}); + call.write({error: false}); + call.end(); + call.on('status', function(status) { + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); + it('should be present when a client stream call fails', function(done) { + var call = client.clientStream(function(err, data) { + assert(err); + }); + call.write({error: false}); + call.write({error: true}); + call.end(); + call.on('status', function(status) { + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); + it('should be present when a server stream call succeeds', function(done) { + var call = client.serverStream({error: false}); + call.on('data', function(){}); + call.on('status', function(status) { + assert.strictEqual(status.code, grpc.status.OK); + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); + it('should be present when a server stream call fails', function(done) { + var call = client.serverStream({error: true}); + call.on('data', function(){}); + call.on('status', function(status) { + assert.notStrictEqual(status.code, grpc.status.OK); + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); + it('should be present when a bidi stream succeeds', function(done) { + var call = client.bidiStream(); + call.write({error: false}); + call.write({error: false}); + call.end(); + call.on('data', function(){}); + call.on('status', function(status) { + assert.strictEqual(status.code, grpc.status.OK); + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); + it('should be present when a bidi stream fails', function(done) { + var call = client.bidiStream(); + call.write({error: false}); + call.write({error: true}); + call.end(); + call.on('data', function(){}); + call.on('status', function(status) { + assert.notStrictEqual(status.code, grpc.status.OK); + assert.deepEqual(status.metadata.metadata, ['yes']); + done(); + }); + }); +}); describe('Cancelling surface client', function() { var client; var server; @@ -89,7 +301,7 @@ describe('Cancelling surface client', function() { } }); var port = server.bind('localhost:0'); - var Client = surface_client.makeClientConstructor(mathService); + var Client = surface_client.makeProtobufClientConstructor(mathService); client = new Client('localhost:' + port); }); after(function() { diff --git a/src/node/test/test_service.proto b/src/node/test/test_service.proto new file mode 100644 index 0000000000..5d3d891841 --- /dev/null +++ b/src/node/test/test_service.proto @@ -0,0 +1,52 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +message Request { + optional bool error = 1; +} + +message Response { + optional int32 count = 1; +} + +service TestService { + rpc Unary (Request) returns (Response) { + } + + rpc ClientStream (stream Request) returns (Response) { + } + + rpc ServerStream (Request) returns (stream Response) { + } + + rpc BidiStream (stream Request) returns (stream Response) { + } +}
\ No newline at end of file diff --git a/src/php/bin/generate_proto_php.sh b/src/php/bin/generate_proto_php.sh new file mode 100755 index 0000000000..16f93747ab --- /dev/null +++ b/src/php/bin/generate_proto_php.sh @@ -0,0 +1,40 @@ +#!/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 +cd $(dirname $0) + +gen_code='../tests/generated_code' +interop='../tests/interop' + +protoc-gen-php -i $gen_code -o $gen_code $gen_code/math.proto + +protoc-gen-php -i $interop -o $interop $interop/test.proto diff --git a/src/php/bin/interop_client.sh b/src/php/bin/interop_client.sh index 2c61ea8aa0..22e4a493c4 100755 --- a/src/php/bin/interop_client.sh +++ b/src/php/bin/interop_client.sh @@ -31,5 +31,8 @@ set +e cd $(dirname $0) -php -d extension_dir=../ext/grpc/modules/ -d extension=grpc.so \ + +module_dir=`php --version | grep -q 'PHP 5.6' && echo '../ext/grpc' || echo '../ext/grpc/modules'` + +php -d extension_dir=$module_dir -d extension=grpc.so \ ../tests/interop/interop_client.php $@ 1>&2 diff --git a/src/php/bin/run_tests.sh b/src/php/bin/run_tests.sh index c3358ed899..1335672e9e 100755 --- a/src/php/bin/run_tests.sh +++ b/src/php/bin/run_tests.sh @@ -34,13 +34,15 @@ set -e cd $(dirname $0) default_extension_dir=`php -i | grep extension_dir | sed 's/.*=> //g'` +module_dir=`php --version | grep -q 'PHP 5.6' && echo '../ext/grpc' || echo '../ext/grpc/modules'` + # sym-link in system supplied extensions for f in $default_extension_dir/*.so do - ln -s $f ../ext/grpc/modules/$(basename $f) &> /dev/null || true + ln -s $f $module_dir/$(basename $f) &> /dev/null || true done php \ - -d extension_dir=../ext/grpc/modules/ \ + -d extension_dir=$module_dir \ -d extension=grpc.so \ `which phpunit` -v --debug --strict ../tests/unit_tests diff --git a/src/php/composer.json b/src/php/composer.json new file mode 100644 index 0000000000..3c0cb37231 --- /dev/null +++ b/src/php/composer.json @@ -0,0 +1,15 @@ +{ + "name": "grpc/grpc", + "description": "gRPC library for PHP", + "version": "0.5.0", + "homepage": "http://grpc.io", + "license": "BSD-3-Clause", + "require": { + "php": ">=5.5.0" + }, + "autoload": { + "psr-4": { + "Grpc\\": "lib/Grpc/" + } + } +} diff --git a/src/php/composer.lock b/src/php/composer.lock new file mode 100644 index 0000000000..47fc70fd2d --- /dev/null +++ b/src/php/composer.lock @@ -0,0 +1,19 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "65467a098f5fd8b8fe5f7f6e10226f8a", + "packages": [], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.5.0" + }, + "platform-dev": [] +} diff --git a/src/php/ext/grpc/byte_buffer.c b/src/php/ext/grpc/byte_buffer.c index 1ced1bf3f0..4f3e6b67af 100644 --- a/src/php/ext/grpc/byte_buffer.c +++ b/src/php/ext/grpc/byte_buffer.c @@ -35,18 +35,18 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> +#include <ext/spl/spl_exceptions.h> #include "php_grpc.h" #include <string.h> #include "byte_buffer.h" -#include "grpc/grpc.h" -#include "grpc/support/slice.h" +#include <grpc/grpc.h> +#include <grpc/support/slice.h> grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) { gpr_slice slice = gpr_slice_from_copied_buffer(string, length); @@ -57,6 +57,11 @@ grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length) { void byte_buffer_to_string(grpc_byte_buffer *buffer, char **out_string, size_t *out_length) { + if (buffer == NULL) { + *out_string = NULL; + *out_length = 0; + return; + } size_t length = grpc_byte_buffer_length(buffer); char *string = ecalloc(length + 1, sizeof(char)); size_t offset = 0; diff --git a/src/php/ext/grpc/byte_buffer.h b/src/php/ext/grpc/byte_buffer.h index 7a40638591..0e9d1e7145 100644 --- a/src/php/ext/grpc/byte_buffer.h +++ b/src/php/ext/grpc/byte_buffer.h @@ -34,7 +34,7 @@ #ifndef NET_GRPC_PHP_GRPC_BYTE_BUFFER_H_ #define NET_GRPC_PHP_GRPC_BYTE_BUFFER_H_ -#include "grpc/grpc.h" +#include <grpc/grpc.h> grpc_byte_buffer *string_to_byte_buffer(char *string, size_t length); diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 798747109a..b1525e9246 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -37,23 +37,23 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> +#include <ext/spl/spl_exceptions.h> #include "php_grpc.h" -#include "zend_exceptions.h" -#include "zend_hash.h" +#include <zend_exceptions.h> +#include <zend_hash.h> #include <stdbool.h> -#include "grpc/support/log.h" -#include "grpc/grpc.h" +#include <grpc/support/log.h> +#include <grpc/support/alloc.h> +#include <grpc/grpc.h> #include "timeval.h" #include "channel.h" -#include "completion_queue.h" #include "byte_buffer.h" zend_class_entry *grpc_ce_call; @@ -61,7 +61,19 @@ zend_class_entry *grpc_ce_call; /* Frees and destroys an instance of wrapped_grpc_call */ void free_wrapped_grpc_call(void *object TSRMLS_DC) { wrapped_grpc_call *call = (wrapped_grpc_call *)object; + grpc_event *event; if (call->owned && call->wrapped != NULL) { + if (call->queue != NULL) { + grpc_completion_queue_shutdown(call->queue); + event = grpc_completion_queue_next(call->queue, gpr_inf_future); + while (event != NULL) { + if (event->type == GRPC_QUEUE_SHUTDOWN) { + break; + } + event = grpc_completion_queue_next(call->queue, gpr_inf_future); + } + grpc_completion_queue_destroy(call->queue); + } grpc_call_destroy(call->wrapped); } efree(call); @@ -88,17 +100,23 @@ zend_object_value create_wrapped_grpc_call(zend_class_entry *class_type /* Wraps a grpc_call struct in a PHP object. Owned indicates whether the struct should be destroyed at the end of the object's lifecycle */ -zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned) { +zval *grpc_php_wrap_call(grpc_call *wrapped, grpc_completion_queue *queue, + bool owned) { zval *call_object; MAKE_STD_ZVAL(call_object); object_init_ex(call_object, grpc_ce_call); wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(call_object TSRMLS_CC); call->wrapped = wrapped; + call->queue = queue; return call_object; } -zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements) { +/* Creates and returns a PHP array object with the data in a + * grpc_metadata_array. Returns NULL on failure */ +zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array) { + int count = metadata_array->count; + grpc_metadata *elements = metadata_array->metadata; int i; zval *array; zval **data = NULL; @@ -139,6 +157,64 @@ zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements) { return array; } +/* Populates a grpc_metadata_array with the data in a PHP array object. + Returns true on success and false on failure */ +bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { + zval **inner_array; + zval **value; + HashTable *array_hash; + HashPosition array_pointer; + HashTable *inner_array_hash; + HashPosition inner_array_pointer; + char *key; + uint key_len; + ulong index; + if (Z_TYPE_P(array) != IS_ARRAY) { + return false; + } + grpc_metadata_array_init(metadata); + array_hash = Z_ARRVAL_P(array); + for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); + zend_hash_get_current_data_ex(array_hash, (void**)&inner_array, + &array_pointer) == SUCCESS; + zend_hash_move_forward_ex(array_hash, &array_pointer)) { + if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0, + &array_pointer) != HASH_KEY_IS_STRING) { + return false; + } + if (Z_TYPE_P(*inner_array) != IS_ARRAY) { + return false; + } + inner_array_hash = Z_ARRVAL_P(*inner_array); + metadata->capacity += zend_hash_num_elements(inner_array_hash); + } + metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata)); + for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); + zend_hash_get_current_data_ex(array_hash, (void**)&inner_array, + &array_pointer) == SUCCESS; + zend_hash_move_forward_ex(array_hash, &array_pointer)) { + if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0, + &array_pointer) != HASH_KEY_IS_STRING) { + return false; + } + inner_array_hash = Z_ARRVAL_P(*inner_array); + for (zend_hash_internal_pointer_reset_ex(inner_array_hash, + &inner_array_pointer); + zend_hash_get_current_data_ex(inner_array_hash, (void**)&value, + &inner_array_pointer) == SUCCESS; + zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) { + if (Z_TYPE_P(*value) != IS_STRING) { + return false; + } + metadata->metadata[metadata->count].key = key; + metadata->metadata[metadata->count].value = Z_STRVAL_P(*value); + metadata->metadata[metadata->count].value_length = Z_STRLEN_P(*value); + metadata->count += 1; + } + } + return true; +} + /** * Constructs a new instance of the Call class. * @param Channel $channel The channel to associate the call with. Must not be @@ -157,9 +233,10 @@ PHP_METHOD(Call, __construct) { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO", &channel_obj, grpc_ce_channel, &method, &method_len, &deadline_obj, grpc_ce_timeval) == FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Call expects a Channel, a String, and a Timeval", - 1 TSRMLS_CC); + zend_throw_exception( + spl_ce_InvalidArgumentException, + "Call expects a Channel, a String, and a Timeval", + 1 TSRMLS_CC); return; } wrapped_grpc_channel *channel = @@ -175,289 +252,253 @@ PHP_METHOD(Call, __construct) { wrapped_grpc_timeval *deadline = (wrapped_grpc_timeval *)zend_object_store_get_object( deadline_obj TSRMLS_CC); - call->wrapped = grpc_channel_create_call_old( - channel->wrapped, method, channel->target, deadline->wrapped); + call->queue = grpc_completion_queue_create(); + call->wrapped = grpc_channel_create_call( + channel->wrapped, call->queue, method, channel->target, + deadline->wrapped); } /** - * Add metadata to the call. All array keys must be strings. If the value is a - * string, it is added as a key/value pair. If it is an array, each value is - * added paired with the same string - * @param array $metadata The metadata to add - * @param long $flags A bitwise combination of the Grpc\WRITE_* constants - * (optional) - * @return Void + * Start a batch of RPC actions. + * @param array batch Array of actions to take + * @return object Object with results of all actions */ -PHP_METHOD(Call, add_metadata) { +PHP_METHOD(Call, startBatch) { wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - grpc_metadata metadata; - grpc_call_error error_code; + grpc_op ops[8]; + size_t op_num = 0; zval *array; - zval **inner_array; zval **value; + zval **inner_value; HashTable *array_hash; HashPosition array_pointer; - HashTable *inner_array_hash; - HashPosition inner_array_pointer; + HashTable *status_hash; char *key; uint key_len; ulong index; - long flags = 0; - /* "a|l" == 1 array, 1 optional long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &flags) == + grpc_metadata_array metadata; + grpc_metadata_array trailing_metadata; + grpc_metadata_array recv_metadata; + grpc_metadata_array recv_trailing_metadata; + grpc_status_code status; + char *status_details = NULL; + size_t status_details_capacity = 0; + grpc_byte_buffer *message; + int cancelled; + grpc_call_error error; + grpc_event *event; + zval *result; + char *message_str; + size_t message_len; + zval *recv_status; + grpc_metadata_array_init(&metadata); + grpc_metadata_array_init(&trailing_metadata); + grpc_metadata_array_init(&recv_metadata); + grpc_metadata_array_init(&recv_trailing_metadata); + MAKE_STD_ZVAL(result); + object_init(result); + /* "a" == 1 array */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, - "add_metadata expects an array and an optional long", - 1 TSRMLS_CC); - return; + "start_batch expects an array", 1 TSRMLS_CC); + goto cleanup; } array_hash = Z_ARRVAL_P(array); for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); - zend_hash_get_current_data_ex(array_hash, (void**)&inner_array, + zend_hash_get_current_data_ex(array_hash, (void**)&value, &array_pointer) == SUCCESS; zend_hash_move_forward_ex(array_hash, &array_pointer)) { if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0, - &array_pointer) != HASH_KEY_IS_STRING) { + &array_pointer) != HASH_KEY_IS_LONG) { zend_throw_exception(spl_ce_InvalidArgumentException, - "metadata keys must be strings", 1 TSRMLS_CC); - return; + "batch keys must be integers", 1 TSRMLS_CC); + goto cleanup; } - if (Z_TYPE_P(*inner_array) != IS_ARRAY) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "metadata values must be arrays", - 1 TSRMLS_CC); - return; - } - inner_array_hash = Z_ARRVAL_P(*inner_array); - for (zend_hash_internal_pointer_reset_ex(inner_array_hash, - &inner_array_pointer); - zend_hash_get_current_data_ex(inner_array_hash, (void**)&value, - &inner_array_pointer) == SUCCESS; - zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) { - if (Z_TYPE_P(*value) != IS_STRING) { + switch(index) { + case GRPC_OP_SEND_INITIAL_METADATA: + if (!create_metadata_array(*value, &metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad metadata value given", 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_initial_metadata.count = + metadata.count; + ops[op_num].data.send_initial_metadata.metadata = + metadata.metadata; + break; + case GRPC_OP_SEND_MESSAGE: + if (Z_TYPE_PP(value) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected a string for send message", + 1 TSRMLS_CC); + } + ops[op_num].data.send_message = + string_to_byte_buffer(Z_STRVAL_PP(value), Z_STRLEN_PP(value)); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + status_hash = Z_ARRVAL_PP(value); + if (zend_hash_find(status_hash, "metadata", sizeof("metadata"), + (void **)&inner_value) == SUCCESS) { + if (!create_metadata_array(*inner_value, &trailing_metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad trailing metadata value given", + 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_status_from_server.trailing_metadata = + trailing_metadata.metadata; + ops[op_num].data.send_status_from_server.trailing_metadata_count = + trailing_metadata.count; + } + if (zend_hash_find(status_hash, "code", sizeof("code"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_PP(inner_value) != IS_LONG) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Status code must be an integer", + 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_status_from_server.status = + Z_LVAL_PP(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Integer status code is required", + 1 TSRMLS_CC); + goto cleanup; + } + if (zend_hash_find(status_hash, "details", sizeof("details"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_PP(inner_value) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Status details must be a string", + 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_status_from_server.status_details = + Z_STRVAL_PP(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "String status details is required", + 1 TSRMLS_CC); + goto cleanup; + } + break; + case GRPC_OP_RECV_INITIAL_METADATA: + ops[op_num].data.recv_initial_metadata = &recv_metadata; + break; + case GRPC_OP_RECV_MESSAGE: + ops[op_num].data.recv_message = &message; + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + ops[op_num].data.recv_status_on_client.trailing_metadata = + &recv_trailing_metadata; + ops[op_num].data.recv_status_on_client.status = &status; + ops[op_num].data.recv_status_on_client.status_details = + &status_details; + ops[op_num].data.recv_status_on_client.status_details_capacity = + &status_details_capacity; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + ops[op_num].data.recv_close_on_server.cancelled = &cancelled; + break; + default: zend_throw_exception(spl_ce_InvalidArgumentException, - "metadata values must be arrays of strings", - 1 TSRMLS_CC); - return; - } - metadata.key = key; - metadata.value = Z_STRVAL_P(*value); - metadata.value_length = Z_STRLEN_P(*value); - error_code = grpc_call_add_metadata_old(call->wrapped, &metadata, 0u); - MAYBE_THROW_CALL_ERROR(add_metadata, error_code); + "Unrecognized key in batch", 1 TSRMLS_CC); + goto cleanup; } + ops[op_num].op = (grpc_op_type)index; + op_num++; } -} - -/** - * Invoke the RPC. Starts sending metadata and request headers over the wire - * @param CompletionQueue $queue The completion queue to use with this call - * @param long $metadata_tag The tag to associate with returned metadata - * @param long $finished_tag The tag to associate with the finished event - * @param long $flags A bitwise combination of the Grpc\WRITE_* constants - * (optional) - * @return Void - */ -PHP_METHOD(Call, invoke) { - grpc_call_error error_code; - long tag1; - long tag2; - zval *queue_obj; - long flags = 0; - /* "Oll|l" == 1 Object, 3 mandatory longs, 1 optional long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oll|l", &queue_obj, - grpc_ce_completion_queue, &tag1, &tag2, - &flags) == FAILURE) { - zend_throw_exception( - spl_ce_InvalidArgumentException, - "invoke needs a CompletionQueue, 2 longs, and an optional long", - 1 TSRMLS_CC); - return; + error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped); + if (error != GRPC_CALL_OK) { + zend_throw_exception(spl_ce_LogicException, + "start_batch was called incorrectly", + (long)error TSRMLS_CC); + goto cleanup; } - add_property_zval(getThis(), "completion_queue", queue_obj); - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - wrapped_grpc_completion_queue *queue = - (wrapped_grpc_completion_queue *)zend_object_store_get_object( - queue_obj TSRMLS_CC); - error_code = grpc_call_invoke_old(call->wrapped, queue->wrapped, (void *)tag1, - (void *)tag2, (gpr_uint32)flags); - MAYBE_THROW_CALL_ERROR(invoke, error_code); -} - -/** - * Accept an incoming RPC, binding a completion queue to it. To be called after - * adding metadata to the call, but before sending messages. Can only be called - * on the server - * @param CompletionQueue $queue The completion queue to use with this call - * @param long $finished_tag The tag to associate with the finished event - * @param long $flags A bitwise combination of the Grpc\WRITE_* constants - * (optional) - * @return Void - */ -PHP_METHOD(Call, server_accept) { - long tag; - zval *queue_obj; - grpc_call_error error_code; - /* "Ol|l" == 1 Object, 1 long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &queue_obj, - grpc_ce_completion_queue, &tag) == FAILURE) { - zend_throw_exception( - spl_ce_InvalidArgumentException, - "server_accept expects a CompletionQueue, a long, and an optional long", - 1 TSRMLS_CC); - return; - } - add_property_zval(getThis(), "completion_queue", queue_obj); - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - wrapped_grpc_completion_queue *queue = - (wrapped_grpc_completion_queue *)zend_object_store_get_object( - queue_obj TSRMLS_CC); - error_code = - grpc_call_server_accept_old(call->wrapped, queue->wrapped, (void *)tag); - MAYBE_THROW_CALL_ERROR(server_accept, error_code); -} - -PHP_METHOD(Call, server_end_initial_metadata) { - grpc_call_error error_code; - long flags = 0; - /* "|l" == 1 optional long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &flags) == - FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "server_end_initial_metadata expects an optional long", - 1 TSRMLS_CC); - } - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - error_code = grpc_call_server_end_initial_metadata_old(call->wrapped, flags); - MAYBE_THROW_CALL_ERROR(server_end_initial_metadata, error_code); -} - -/** - * Called by clients to cancel an RPC on the server. - * @return Void - */ -PHP_METHOD(Call, cancel) { - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - grpc_call_error error_code = grpc_call_cancel(call->wrapped); - MAYBE_THROW_CALL_ERROR(cancel, error_code); -} - -/** - * Queue a byte buffer for writing - * @param string $buffer The buffer to queue for writing - * @param long $tag The tag to associate with this write - * @param long $flags A bitwise combination of the Grpc\WRITE_* constants - * (optional) - * @return Void - */ -PHP_METHOD(Call, start_write) { - grpc_call_error error_code; - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - char *buffer; - int buffer_len; - long tag; - long flags = 0; - /* "Ol|l" == 1 Object, 1 mandatory long, 1 optional long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|l", &buffer, - &buffer_len, &tag, &flags) == FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "start_write expects a string and an optional long", + event = grpc_completion_queue_pluck(call->queue, call->wrapped, + gpr_inf_future); + if (event->data.op_complete != GRPC_OP_OK) { + zend_throw_exception(spl_ce_LogicException, + "The batch failed for some reason", 1 TSRMLS_CC); - return; + goto cleanup; } - error_code = grpc_call_start_write_old( - call->wrapped, string_to_byte_buffer(buffer, buffer_len), (void *)tag, - (gpr_uint32)flags); - MAYBE_THROW_CALL_ERROR(start_write, error_code); -} - -/** - * Queue a status for writing - * @param long $status_code The status code to send - * @param string $status_details The status details to send - * @param long $tag The tag to associate with this status - * @return Void - */ -PHP_METHOD(Call, start_write_status) { - grpc_call_error error_code; - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - long status_code; - int status_details_length; - long tag; - char *status_details; - /* "lsl" == 1 long, 1 string, 1 long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lsl", &status_code, - &status_details, &status_details_length, - &tag) == FAILURE) { - zend_throw_exception( - spl_ce_InvalidArgumentException, - "start_write_status expects a long, a string, and a long", 1 TSRMLS_CC); - return; + for (int i = 0; i < op_num; i++) { + switch(ops[i].op) { + case GRPC_OP_SEND_INITIAL_METADATA: + add_property_bool(result, "send_metadata", true); + break; + case GRPC_OP_SEND_MESSAGE: + add_property_bool(result, "send_message", true); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + add_property_bool(result, "send_close", true); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + add_property_bool(result, "send_status", true); + break; + case GRPC_OP_RECV_INITIAL_METADATA: + array = grpc_parse_metadata_array(&recv_metadata); + add_property_zval(result, "metadata", array); + Z_DELREF_P(array); + break; + case GRPC_OP_RECV_MESSAGE: + byte_buffer_to_string(message, &message_str, &message_len); + if (message_str == NULL) { + add_property_null(result, "message"); + } else { + add_property_stringl(result, "message", message_str, message_len, + false); + } + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + MAKE_STD_ZVAL(recv_status); + object_init(recv_status); + array = grpc_parse_metadata_array(&recv_trailing_metadata); + add_property_zval(recv_status, "metadata", array); + Z_DELREF_P(array); + add_property_long(recv_status, "code", status); + add_property_string(recv_status, "details", status_details, true); + add_property_zval(result, "status", recv_status); + Z_DELREF_P(recv_status); + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + add_property_bool(result, "cancelled", cancelled); + break; + default: + break; + } } - error_code = grpc_call_start_write_status_old(call->wrapped, - (grpc_status_code)status_code, - status_details, (void *)tag); - MAYBE_THROW_CALL_ERROR(start_write_status, error_code); -} - -/** - * Indicate that there are no more messages to send - * @return Void - */ -PHP_METHOD(Call, writes_done) { - grpc_call_error error_code; - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - long tag; - /* "l" == 1 long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag) == FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "writes_done expects a long", 1 TSRMLS_CC); - return; +cleanup: + grpc_metadata_array_destroy(&metadata); + grpc_metadata_array_destroy(&trailing_metadata); + grpc_metadata_array_destroy(&recv_metadata); + grpc_metadata_array_destroy(&recv_trailing_metadata); + if (status_details != NULL) { + gpr_free(status_details); } - error_code = grpc_call_writes_done_old(call->wrapped, (void *)tag); - MAYBE_THROW_CALL_ERROR(writes_done, error_code); + RETURN_DESTROY_ZVAL(result); } /** - * Initiate a read on a call. Output event contains a byte buffer with the - * result of the read - * @param long $tag The tag to associate with this read - * @return Void + * Cancel the call. This will cause the call to end with STATUS_CANCELLED if it + * has not already ended with another status. */ -PHP_METHOD(Call, start_read) { - grpc_call_error error_code; +PHP_METHOD(Call, cancel) { wrapped_grpc_call *call = (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - long tag; - /* "l" == 1 long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag) == FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "start_read expects a long", 1 TSRMLS_CC); - return; - } - error_code = grpc_call_start_read_old(call->wrapped, (void *)tag); - MAYBE_THROW_CALL_ERROR(start_read, error_code); + grpc_call_cancel(call->wrapped); } static zend_function_entry call_methods[] = { PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Call, server_accept, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, server_end_initial_metadata, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, add_metadata, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, invoke, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, start_read, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, start_write, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, start_write_status, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, writes_done, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; + PHP_ME(Call, startBatch, 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/call.h b/src/php/ext/grpc/call.h index bce5d82974..e7eb9a75e2 100644 --- a/src/php/ext/grpc/call.h +++ b/src/php/ext/grpc/call.h @@ -38,23 +38,12 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> #include "php_grpc.h" -#include "grpc/grpc.h" - -// Throw an exception if error_code is not OK -#define MAYBE_THROW_CALL_ERROR(func_name, error_code) \ - do { \ - if (error_code != GRPC_CALL_OK) { \ - zend_throw_exception(spl_ce_LogicException, \ - #func_name " was called incorrectly", \ - (long)error_code TSRMLS_CC); \ - return; \ - } \ - } while (0) +#include <grpc/grpc.h> /* Class entry for the Call PHP class */ extern zend_class_entry *grpc_ce_call; @@ -65,16 +54,18 @@ typedef struct wrapped_grpc_call { bool owned; grpc_call *wrapped; + grpc_completion_queue *queue; } wrapped_grpc_call; /* Initializes the Call PHP class */ void grpc_init_call(TSRMLS_D); /* Creates a Call object that wraps the given grpc_call struct */ -zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned); +zval *grpc_php_wrap_call(grpc_call *wrapped, grpc_completion_queue *queue, + bool owned); /* Creates and returns a PHP associative array of metadata from a C array of * call metadata */ -zval *grpc_call_create_metadata_array(int count, grpc_metadata *elements); +zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array); #endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */ diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index 5e99332fab..b8262db162 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -37,21 +37,20 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> +#include <ext/spl/spl_exceptions.h> #include "php_grpc.h" -#include "zend_exceptions.h" +#include <zend_exceptions.h> #include <stdbool.h> -#include "grpc/grpc.h" -#include "grpc/support/log.h" -#include "grpc/grpc_security.h" +#include <grpc/grpc.h> +#include <grpc/support/log.h> +#include <grpc/grpc_security.h> -#include "completion_queue.h" #include "server.h" #include "credentials.h" @@ -63,6 +62,7 @@ void free_wrapped_grpc_channel(void *object TSRMLS_DC) { if (channel->wrapped != NULL) { grpc_channel_destroy(channel->wrapped); } + efree(channel->target); efree(channel); } @@ -139,6 +139,9 @@ PHP_METHOD(Channel, __construct) { HashTable *array_hash; zval **creds_obj = NULL; wrapped_grpc_credentials *creds = NULL; + zval **override_obj; + char *override; + int override_len; /* "s|a" == 1 string, 1 optional array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &target, &target_length, &args_array) == FAILURE) { @@ -146,6 +149,8 @@ PHP_METHOD(Channel, __construct) { "Channel expects a string and an array", 1 TSRMLS_CC); return; } + override = target; + override_len = target_length; if (args_array == NULL) { channel->wrapped = grpc_channel_create(target, NULL); } else { @@ -162,6 +167,19 @@ PHP_METHOD(Channel, __construct) { *creds_obj TSRMLS_CC); zend_hash_del(array_hash, "credentials", 12); } + if (zend_hash_find(array_hash, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + sizeof(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG), + (void **)&override_obj) == SUCCESS) { + if (Z_TYPE_PP(override_obj) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG + " must be a string", + 1 TSRMLS_CC); + return; + } + override = Z_STRVAL_PP(override_obj); + override_len = Z_STRLEN_PP(override_obj); + } php_grpc_read_args_array(args_array, &args); if (creds == NULL) { channel->wrapped = grpc_channel_create(target, &args); @@ -172,8 +190,8 @@ PHP_METHOD(Channel, __construct) { } efree(args.args); } - channel->target = ecalloc(target_length + 1, sizeof(char)); - memcpy(channel->target, target, target_length); + channel->target = ecalloc(override_len + 1, sizeof(char)); + memcpy(channel->target, override, override_len); } /** diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h index 2c79668a4d..c13fa4c6d7 100755 --- a/src/php/ext/grpc/channel.h +++ b/src/php/ext/grpc/channel.h @@ -38,12 +38,12 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> #include "php_grpc.h" -#include "grpc/grpc.h" +#include <grpc/grpc.h> /* Class entry for the PHP Channel class */ extern zend_class_entry *grpc_ce_channel; diff --git a/src/php/ext/grpc/completion_queue.c b/src/php/ext/grpc/completion_queue.c deleted file mode 100644 index 93abf5df36..0000000000 --- a/src/php/ext/grpc/completion_queue.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "completion_queue.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" -#include "php_grpc.h" - -#include "zend_exceptions.h" - -#include <stdbool.h> - -#include "grpc/grpc.h" - -#include "event.h" -#include "timeval.h" - -zend_class_entry *grpc_ce_completion_queue; - -/* Frees and destroys a wrapped instance of grpc_completion_queue */ -void free_wrapped_grpc_completion_queue(void *object TSRMLS_DC) { - wrapped_grpc_completion_queue *queue = NULL; - grpc_event *event; - queue = (wrapped_grpc_completion_queue *)object; - if (queue->wrapped != NULL) { - grpc_completion_queue_shutdown(queue->wrapped); - event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future); - while (event != NULL) { - if (event->type == GRPC_QUEUE_SHUTDOWN) { - break; - } - event = grpc_completion_queue_next(queue->wrapped, gpr_inf_future); - } - grpc_completion_queue_destroy(queue->wrapped); - } - efree(queue); -} - -/* Initializes an instance of wrapped_grpc_channel to be associated with an - * object of a class specified by class_type */ -zend_object_value create_wrapped_grpc_completion_queue( - zend_class_entry *class_type TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_completion_queue *intern; - - intern = (wrapped_grpc_completion_queue *)emalloc( - sizeof(wrapped_grpc_completion_queue)); - memset(intern, 0, sizeof(wrapped_grpc_completion_queue)); - - zend_object_std_init(&intern->std, class_type TSRMLS_CC); - object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_completion_queue, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; -} - -/** - * Construct an instance of CompletionQueue - */ -PHP_METHOD(CompletionQueue, __construct) { - wrapped_grpc_completion_queue *queue = - (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis() - TSRMLS_CC); - queue->wrapped = grpc_completion_queue_create(); -} - -/** - * Blocks until an event is available, the completion queue is being shutdown, - * or timeout is reached. Returns NULL on timeout, otherwise the event that - * occurred. Callers should call event.finish once they have processed the - * event. - * @param Timeval $timeout The timeout for the event - * @return Event The event that occurred - */ -PHP_METHOD(CompletionQueue, next) { - zval *timeout; - /* "O" == 1 Object */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &timeout, - grpc_ce_timeval) == FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "next needs a Timeval", 1 TSRMLS_CC); - return; - } - wrapped_grpc_completion_queue *completion_queue = - (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis() - TSRMLS_CC); - wrapped_grpc_timeval *wrapped_timeout = - (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC); - grpc_event *event = grpc_completion_queue_next(completion_queue->wrapped, - wrapped_timeout->wrapped); - if (event == NULL) { - RETURN_NULL(); - } - zval *wrapped_event = grpc_php_convert_event(event); - RETURN_DESTROY_ZVAL(wrapped_event); -} - -PHP_METHOD(CompletionQueue, pluck) { - long tag; - zval *timeout; - /* "lO" == 1 long, 1 Object */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO", &tag, &timeout, - grpc_ce_timeval) == FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "pluck needs a long and a Timeval", 1 TSRMLS_CC); - } - wrapped_grpc_completion_queue *completion_queue = - (wrapped_grpc_completion_queue *)zend_object_store_get_object(getThis() - TSRMLS_CC); - wrapped_grpc_timeval *wrapped_timeout = - (wrapped_grpc_timeval *)zend_object_store_get_object(timeout TSRMLS_CC); - grpc_event *event = grpc_completion_queue_pluck( - completion_queue->wrapped, (void *)tag, wrapped_timeout->wrapped); - if (event == NULL) { - RETURN_NULL(); - } - zval *wrapped_event = grpc_php_convert_event(event); - RETURN_DESTROY_ZVAL(wrapped_event); -} - -static zend_function_entry completion_queue_methods[] = { - PHP_ME(CompletionQueue, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(CompletionQueue, next, NULL, ZEND_ACC_PUBLIC) - PHP_ME(CompletionQueue, pluck, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; - -void grpc_init_completion_queue(TSRMLS_D) { - zend_class_entry ce; - INIT_CLASS_ENTRY(ce, "Grpc\\CompletionQueue", completion_queue_methods); - ce.create_object = create_wrapped_grpc_completion_queue; - grpc_ce_completion_queue = zend_register_internal_class(&ce TSRMLS_CC); -} diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4 index 27c67781e7..11778e3bb6 100755 --- a/src/php/ext/grpc/config.m4 +++ b/src/php/ext/grpc/config.m4 @@ -66,5 +66,5 @@ if test "$PHP_GRPC" != "no"; then PHP_SUBST(GRPC_SHARED_LIBADD) - PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c channel.c completion_queue.c credentials.c event.c timeval.c server.c server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -pedantic -std=c99) + PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c channel.c credentials.c timeval.c server.c server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11) fi diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c index a94b0eac2d..a262b9981f 100644 --- a/src/php/ext/grpc/credentials.c +++ b/src/php/ext/grpc/credentials.c @@ -37,17 +37,17 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> +#include <ext/spl/spl_exceptions.h> #include "php_grpc.h" -#include "zend_exceptions.h" -#include "zend_hash.h" +#include <zend_exceptions.h> +#include <zend_hash.h> -#include "grpc/grpc.h" -#include "grpc/grpc_security.h" +#include <grpc/grpc.h> +#include <grpc/grpc_security.h> zend_class_entry *grpc_ce_credentials; diff --git a/src/php/ext/grpc/event.c b/src/php/ext/grpc/event.c deleted file mode 100644 index 452c4b8bcb..0000000000 --- a/src/php/ext/grpc/event.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "event.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_grpc.h" - -#include <stdbool.h> - -#include "grpc/grpc.h" - -#include "byte_buffer.h" -#include "call.h" -#include "timeval.h" - -/* Create a new PHP object containing the event data in the event struct. - event must not be used after this function is called */ -zval *grpc_php_convert_event(grpc_event *event) { - zval *data_object; - char *detail_string; - size_t detail_len; - char *method_string; - size_t method_len; - char *host_string; - size_t host_len; - char *read_string; - size_t read_len; - - zval *event_object; - - if (event == NULL) { - return NULL; - } - - MAKE_STD_ZVAL(event_object); - object_init(event_object); - - add_property_zval( - event_object, "call", - grpc_php_wrap_call(event->call, event->type == GRPC_SERVER_RPC_NEW)); - add_property_long(event_object, "type", event->type); - add_property_long(event_object, "tag", (long)event->tag); - - switch (event->type) { - case GRPC_QUEUE_SHUTDOWN: - add_property_null(event_object, "data"); - break; - case GRPC_READ: - if (event->data.read == NULL) { - add_property_null(event_object, "data"); - } else { - byte_buffer_to_string(event->data.read, &read_string, &read_len); - add_property_stringl(event_object, "data", read_string, read_len, true); - } - break; - case GRPC_WRITE_ACCEPTED: - add_property_long(event_object, "data", (long)event->data.write_accepted); - break; - case GRPC_FINISH_ACCEPTED: - add_property_long(event_object, "data", - (long)event->data.finish_accepted); - break; - case GRPC_CLIENT_METADATA_READ: - data_object = grpc_call_create_metadata_array( - event->data.client_metadata_read.count, - event->data.client_metadata_read.elements); - add_property_zval(event_object, "data", data_object); - break; - case GRPC_FINISHED: - MAKE_STD_ZVAL(data_object); - object_init(data_object); - add_property_long(data_object, "code", event->data.finished.status); - if (event->data.finished.details == NULL) { - add_property_null(data_object, "details"); - } else { - detail_len = strlen(event->data.finished.details); - detail_string = ecalloc(detail_len + 1, sizeof(char)); - memcpy(detail_string, event->data.finished.details, detail_len); - add_property_string(data_object, "details", detail_string, true); - } - add_property_zval(data_object, "metadata", - grpc_call_create_metadata_array( - event->data.finished.metadata_count, - event->data.finished.metadata_elements)); - add_property_zval(event_object, "data", data_object); - break; - case GRPC_SERVER_RPC_NEW: - MAKE_STD_ZVAL(data_object); - object_init(data_object); - method_len = strlen(event->data.server_rpc_new.method); - method_string = ecalloc(method_len + 1, sizeof(char)); - memcpy(method_string, event->data.server_rpc_new.method, method_len); - add_property_string(data_object, "method", method_string, false); - host_len = strlen(event->data.server_rpc_new.host); - host_string = ecalloc(host_len + 1, sizeof(char)); - memcpy(host_string, event->data.server_rpc_new.host, host_len); - add_property_string(data_object, "host", host_string, false); - add_property_zval( - data_object, "absolute_timeout", - grpc_php_wrap_timeval(event->data.server_rpc_new.deadline)); - add_property_zval(data_object, "metadata", - grpc_call_create_metadata_array( - event->data.server_rpc_new.metadata_count, - event->data.server_rpc_new.metadata_elements)); - add_property_zval(event_object, "data", data_object); - break; - default: - add_property_null(event_object, "data"); - break; - } - grpc_event_finish(event); - return event_object; -} diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 67e366c385..3e669ecd17 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -34,8 +34,6 @@ #include "call.h" #include "channel.h" #include "server.h" -#include "completion_queue.h" -#include "event.h" #include "timeval.h" #include "credentials.h" #include "server_credentials.h" @@ -44,9 +42,9 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> #include "php_grpc.h" // ZEND_DECLARE_MODULE_GLOBALS(grpc) @@ -127,27 +125,12 @@ PHP_MINIT_FUNCTION(grpc) { REGISTER_LONG_CONSTANT("Grpc\\CALL_ERROR_INVALID_FLAGS", GRPC_CALL_ERROR_INVALID_FLAGS, CONST_CS); - /* Register op error constants */ - REGISTER_LONG_CONSTANT("Grpc\\OP_OK", GRPC_OP_OK, CONST_CS); - REGISTER_LONG_CONSTANT("Grpc\\OP_ERROR", GRPC_OP_ERROR, CONST_CS); - /* Register flag constants */ REGISTER_LONG_CONSTANT("Grpc\\WRITE_BUFFER_HINT", GRPC_WRITE_BUFFER_HINT, CONST_CS); REGISTER_LONG_CONSTANT("Grpc\\WRITE_NO_COMPRESS", GRPC_WRITE_NO_COMPRESS, CONST_CS); - /* Register completion type constants */ - REGISTER_LONG_CONSTANT("Grpc\\QUEUE_SHUTDOWN", GRPC_QUEUE_SHUTDOWN, CONST_CS); - REGISTER_LONG_CONSTANT("Grpc\\READ", GRPC_READ, CONST_CS); - REGISTER_LONG_CONSTANT("Grpc\\FINISH_ACCEPTED", GRPC_FINISH_ACCEPTED, - CONST_CS); - REGISTER_LONG_CONSTANT("Grpc\\WRITE_ACCEPTED", GRPC_WRITE_ACCEPTED, CONST_CS); - REGISTER_LONG_CONSTANT("Grpc\\CLIENT_METADATA_READ", - GRPC_CLIENT_METADATA_READ, CONST_CS); - REGISTER_LONG_CONSTANT("Grpc\\FINISHED", GRPC_FINISHED, CONST_CS); - REGISTER_LONG_CONSTANT("Grpc\\SERVER_RPC_NEW", GRPC_SERVER_RPC_NEW, CONST_CS); - /* Register status constants */ REGISTER_LONG_CONSTANT("Grpc\\STATUS_OK", GRPC_STATUS_OK, CONST_CS); REGISTER_LONG_CONSTANT("Grpc\\STATUS_CANCELLED", GRPC_STATUS_CANCELLED, @@ -181,10 +164,27 @@ PHP_MINIT_FUNCTION(grpc) { REGISTER_LONG_CONSTANT("Grpc\\STATUS_DATA_LOSS", GRPC_STATUS_DATA_LOSS, CONST_CS); + /* Register op type constants */ + REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_INITIAL_METADATA", + GRPC_OP_SEND_INITIAL_METADATA, CONST_CS); + REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_MESSAGE", + GRPC_OP_SEND_MESSAGE, CONST_CS); + REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_CLOSE_FROM_CLIENT", + GRPC_OP_SEND_CLOSE_FROM_CLIENT, CONST_CS); + REGISTER_LONG_CONSTANT("Grpc\\OP_SEND_STATUS_FROM_SERVER", + GRPC_OP_SEND_STATUS_FROM_SERVER, CONST_CS); + REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_INITIAL_METADATA", + GRPC_OP_RECV_INITIAL_METADATA, CONST_CS); + REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_MESSAGE", + GRPC_OP_RECV_MESSAGE, CONST_CS); + REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_STATUS_ON_CLIENT", + GRPC_OP_RECV_STATUS_ON_CLIENT, CONST_CS); + REGISTER_LONG_CONSTANT("Grpc\\OP_RECV_CLOSE_ON_SERVER", + GRPC_OP_RECV_CLOSE_ON_SERVER, CONST_CS); + grpc_init_call(TSRMLS_C); grpc_init_channel(TSRMLS_C); grpc_init_server(TSRMLS_C); - grpc_init_completion_queue(TSRMLS_C); grpc_init_timeval(TSRMLS_C); grpc_init_credentials(TSRMLS_C); grpc_init_server_credentials(TSRMLS_C); diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c index a5cfd95287..dbb9425619 100644 --- a/src/php/ext/grpc/server.c +++ b/src/php/ext/grpc/server.c @@ -37,30 +37,42 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> +#include <ext/spl/spl_exceptions.h> #include "php_grpc.h" -#include "zend_exceptions.h" +#include <zend_exceptions.h> #include <stdbool.h> -#include "grpc/grpc.h" -#include "grpc/support/log.h" -#include "grpc/grpc_security.h" +#include <grpc/grpc.h> +#include <grpc/support/log.h> +#include <grpc/grpc_security.h> #include "server.h" -#include "completion_queue.h" #include "channel.h" #include "server_credentials.h" +#include "timeval.h" zend_class_entry *grpc_ce_server; /* Frees and destroys an instance of wrapped_grpc_server */ void free_wrapped_grpc_server(void *object TSRMLS_DC) { wrapped_grpc_server *server = (wrapped_grpc_server *)object; + grpc_event *event; + if (server->queue != NULL) { + grpc_completion_queue_shutdown(server->queue); + event = grpc_completion_queue_next(server->queue, gpr_inf_future); + while (event != NULL) { + if (event->type == GRPC_QUEUE_SHUTDOWN) { + break; + } + event = grpc_completion_queue_next(server->queue, gpr_inf_future); + } + grpc_completion_queue_destroy(server->queue); + } if (server->wrapped != NULL) { grpc_server_shutdown(server->wrapped); grpc_server_destroy(server->wrapped); @@ -95,26 +107,22 @@ zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type PHP_METHOD(Server, __construct) { wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); - zval *queue_obj; zval *args_array = NULL; grpc_channel_args args; - /* "O|a" == 1 Object, 1 optional array */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|a", &queue_obj, - grpc_ce_completion_queue, &args_array) == FAILURE) { + /* "|a" == 1 optional array */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &args_array) == + FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Server expects a CompletionQueue and an array", + "Server expects an array", 1 TSRMLS_CC); return; } - add_property_zval(getThis(), "completion_queue", queue_obj); - wrapped_grpc_completion_queue *queue = - (wrapped_grpc_completion_queue *)zend_object_store_get_object( - queue_obj TSRMLS_CC); + server->queue = grpc_completion_queue_create(); if (args_array == NULL) { - server->wrapped = grpc_server_create(queue->wrapped, NULL); + server->wrapped = grpc_server_create(server->queue, NULL); } else { php_grpc_read_args_array(args_array, &args); - server->wrapped = grpc_server_create(queue->wrapped, &args); + server->wrapped = grpc_server_create(server->queue, &args); efree(args.args); } } @@ -125,20 +133,44 @@ PHP_METHOD(Server, __construct) { * @param long $tag_cancel The tag to use if the call is cancelled * @return Void */ -PHP_METHOD(Server, request_call) { +PHP_METHOD(Server, requestCall) { grpc_call_error error_code; wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); - long tag_new; - /* "l" == 1 long */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &tag_new) == - FAILURE) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "request_call expects a long", 1 TSRMLS_CC); - return; + grpc_call *call; + grpc_call_details details; + grpc_metadata_array metadata; + zval *result; + grpc_event *event; + MAKE_STD_ZVAL(result); + object_init(result); + grpc_call_details_init(&details); + grpc_metadata_array_init(&metadata); + error_code = grpc_server_request_call(server->wrapped, &call, &details, + &metadata, server->queue, NULL); + if (error_code != GRPC_CALL_OK) { + zend_throw_exception(spl_ce_LogicException, "request_call failed", + (long)error_code TSRMLS_CC); + goto cleanup; + } + event = grpc_completion_queue_pluck(server->queue, NULL, gpr_inf_future); + if (event->data.op_complete != GRPC_OP_OK) { + zend_throw_exception(spl_ce_LogicException, + "Failed to request a call for some reason", + 1 TSRMLS_CC); + goto cleanup; } - error_code = grpc_server_request_call_old(server->wrapped, (void *)tag_new); - MAYBE_THROW_CALL_ERROR(request_call, error_code); + add_property_zval(result, "call", grpc_php_wrap_call(call, server->queue, + true)); + add_property_string(result, "method", details.method, true); + add_property_string(result, "host", details.host, true); + add_property_zval(result, "absolute_deadline", + grpc_php_wrap_timeval(details.deadline)); + add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata)); +cleanup: + grpc_call_details_destroy(&details); + grpc_metadata_array_destroy(&metadata); + RETURN_DESTROY_ZVAL(result); } /** @@ -146,7 +178,7 @@ PHP_METHOD(Server, request_call) { * @param string $addr The address to add * @return true on success, false on failure */ -PHP_METHOD(Server, add_http2_port) { +PHP_METHOD(Server, addHttp2Port) { wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; @@ -161,14 +193,14 @@ PHP_METHOD(Server, add_http2_port) { RETURN_LONG(grpc_server_add_http2_port(server->wrapped, addr)); } -PHP_METHOD(Server, add_secure_http2_port) { +PHP_METHOD(Server, addSecureHttp2Port) { wrapped_grpc_server *server = (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; int addr_len; zval *creds_obj; /* "sO" == 1 string, 1 object */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len, + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO", &addr, &addr_len, &creds_obj, grpc_ce_server_credentials) == FAILURE) { zend_throw_exception( @@ -195,9 +227,9 @@ PHP_METHOD(Server, start) { static zend_function_entry server_methods[] = { PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Server, request_call, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, add_http2_port, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, add_secure_http2_port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC) PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; void grpc_init_server(TSRMLS_D) { diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h index b55689c581..a2ee2ff5a9 100755 --- a/src/php/ext/grpc/server.h +++ b/src/php/ext/grpc/server.h @@ -38,12 +38,12 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> #include "php_grpc.h" -#include "grpc/grpc.h" +#include <grpc/grpc.h> /* Class entry for the Server PHP class */ extern zend_class_entry *grpc_ce_server; @@ -53,6 +53,7 @@ typedef struct wrapped_grpc_server { zend_object std; grpc_server *wrapped; + grpc_completion_queue *queue; } wrapped_grpc_server; /* Initializes the Server class */ diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index df64e65986..c4c1fabb1a 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -37,17 +37,17 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> +#include <ext/spl/spl_exceptions.h> #include "php_grpc.h" -#include "zend_exceptions.h" -#include "zend_hash.h" +#include <zend_exceptions.h> +#include <zend_hash.h> -#include "grpc/grpc.h" -#include "grpc/grpc_security.h" +#include <grpc/grpc.h> +#include <grpc/grpc_security.h> zend_class_entry *grpc_ce_server_credentials; diff --git a/src/php/ext/grpc/server_credentials.h b/src/php/ext/grpc/server_credentials.h index 8ed3697150..7101d65000 100755 --- a/src/php/ext/grpc/server_credentials.h +++ b/src/php/ext/grpc/server_credentials.h @@ -38,13 +38,13 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> #include "php_grpc.h" -#include "grpc/grpc.h" -#include "grpc/grpc_security.h" +#include <grpc/grpc.h> +#include <grpc/grpc_security.h> /* Class entry for the Server_Credentials PHP class */ extern zend_class_entry *grpc_ce_server_credentials; diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c index f90f0062ba..8a278d6760 100644 --- a/src/php/ext/grpc/timeval.c +++ b/src/php/ext/grpc/timeval.c @@ -37,18 +37,18 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "ext/spl/spl_exceptions.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> +#include <ext/spl/spl_exceptions.h> #include "php_grpc.h" -#include "zend_exceptions.h" +#include <zend_exceptions.h> #include <stdbool.h> -#include "grpc/grpc.h" -#include "grpc/support/time.h" +#include <grpc/grpc.h> +#include <grpc/support/time.h> zend_class_entry *grpc_ce_timeval; @@ -227,7 +227,7 @@ PHP_METHOD(Timeval, zero) { * Returns the infinite future time value as a timeval object * @return Timeval Infinite future time value */ -PHP_METHOD(Timeval, inf_future) { +PHP_METHOD(Timeval, infFuture) { zval *grpc_php_timeval_inf_future = grpc_php_wrap_timeval(gpr_inf_future); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future); } @@ -236,7 +236,7 @@ PHP_METHOD(Timeval, inf_future) { * Returns the infinite past time value as a timeval object * @return Timeval Infinite past time value */ -PHP_METHOD(Timeval, inf_past) { +PHP_METHOD(Timeval, infPast) { zval *grpc_php_timeval_inf_past = grpc_php_wrap_timeval(gpr_inf_past); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past); } @@ -245,7 +245,7 @@ PHP_METHOD(Timeval, inf_past) { * Sleep until this time, interpreted as an absolute timeout * @return void */ -PHP_METHOD(Timeval, sleep_until) { +PHP_METHOD(Timeval, sleepUntil) { wrapped_grpc_timeval *this = (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); gpr_sleep_until(this->wrapped); @@ -255,11 +255,11 @@ static zend_function_entry timeval_methods[] = { PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC) PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, inf_future, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, inf_past, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, sleep_until, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC) PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC) PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; diff --git a/src/php/ext/grpc/timeval.h b/src/php/ext/grpc/timeval.h index e3183f691d..07cef037cb 100755 --- a/src/php/ext/grpc/timeval.h +++ b/src/php/ext/grpc/timeval.h @@ -38,13 +38,13 @@ #include "config.h" #endif -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" +#include <php.h> +#include <php_ini.h> +#include <ext/standard/info.h> #include "php_grpc.h" -#include "grpc/grpc.h" -#include "grpc/support/time.h" +#include <grpc/grpc.h> +#include <grpc/support/time.h> /* Class entry for the Timeval PHP Class */ extern zend_class_entry *grpc_ce_timeval; diff --git a/src/php/lib/Grpc/BidiStreamingSurfaceActiveCall.php b/src/php/lib/Grpc/AbstractCall.php index 0459f21e27..1add972589 100755..100644 --- a/src/php/lib/Grpc/BidiStreamingSurfaceActiveCall.php +++ b/src/php/lib/Grpc/AbstractCall.php @@ -32,44 +32,47 @@ * */ namespace Grpc; -require_once realpath(dirname(__FILE__) . '/../autoload.php'); -/** - * Represents an active call that allows for sending and recieving messages in - * streams in any order. - */ -class BidiStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall { +abstract class AbstractCall { + + protected $call; + protected $deserialize; + protected $metadata; /** - * Reads the next value from the server. - * @return The next value from the server, or null if there is none + * Create a new Call wrapper object. + * @param Channel $channel The channel to communicate on + * @param string $method The method to call on the remote server */ - public function read() { - return $this->_read(); + public function __construct(Channel $channel, $method, $deserialize) { + $this->call = new Call($channel, $method, Timeval::infFuture()); + $this->deserialize = $deserialize; + $this->metadata = null; } /** - * Writes a single message to the server. This cannot be called after - * writesDone is called. - * @param $value The message to send + * @return The metadata sent by the server. */ - public function write($value) { - $this->_write($value); + public function getMetadata() { + return $this->metadata; } /** - * Indicate that no more writes will be sent + * Cancels the call */ - public function writesDone() { - $this->_writesDone(); + public function cancel() { + $this->call->cancel(); } /** - * Wait for the server to send the status, and return it. - * @return object The status object, with integer $code and string $details - * members + * Deserialize a response value to an object. + * @param string $value The binary value to deserialize + * @return The deserialized value */ - public function getStatus() { - return $this->_getStatus(); + protected function deserializeResponse($value) { + if ($value === null) { + return null; + } + return call_user_func($this->deserialize, $value); } -} +}
\ No newline at end of file diff --git a/src/php/lib/Grpc/ActiveCall.php b/src/php/lib/Grpc/ActiveCall.php deleted file mode 100755 index f0d0d55582..0000000000 --- a/src/php/lib/Grpc/ActiveCall.php +++ /dev/null @@ -1,123 +0,0 @@ -<?php -/* - * - * 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. - * - */ -namespace Grpc; -require_once realpath(dirname(__FILE__) . '/../autoload.php'); - -/** - * Represents an active call that allows sending and recieving binary data - */ -class ActiveCall { - private $completion_queue; - private $call; - private $flags; - private $metadata; - - /** - * Create a new active call. - * @param Channel $channel The channel to communicate on - * @param string $method The method to call on the remote server - * @param array $metadata Metadata to send with the call, if applicable - * @param long $flags Write flags to use with this call - */ - public function __construct(Channel $channel, - $method, - $metadata = array(), - $flags = 0) { - $this->completion_queue = new CompletionQueue(); - $this->call = new Call($channel, $method, Timeval::inf_future()); - $this->call->add_metadata($metadata, 0); - $this->flags = $flags; - - // Invoke the call. - $this->call->invoke($this->completion_queue, - CLIENT_METADATA_READ, - FINISHED, 0); - $metadata_event = $this->completion_queue->pluck(CLIENT_METADATA_READ, - Timeval::inf_future()); - $this->metadata = $metadata_event->data; - } - - /** - * @return The metadata sent by the server. - */ - public function getMetadata() { - return $this->metadata; - } - - /** - * Cancels the call - */ - public function cancel() { - $this->call->cancel(); - } - - /** - * Read a single message from the server. - * @return The next message from the server, or null if there is none. - */ - public function read() { - $this->call->start_read(READ); - $read_event = $this->completion_queue->pluck(READ, Timeval::inf_future()); - return $read_event->data; - } - - /** - * Write a single message to the server. This cannot be called after - * writesDone is called. - * @param ByteBuffer $data The data to write - */ - public function write($data) { - $this->call->start_write($data, WRITE_ACCEPTED, $this->flags); - $this->completion_queue->pluck(WRITE_ACCEPTED, Timeval::inf_future()); - } - - /** - * Indicate that no more writes will be sent. - */ - public function writesDone() { - $this->call->writes_done(FINISH_ACCEPTED); - $this->completion_queue->pluck(FINISH_ACCEPTED, Timeval::inf_future()); - } - - /** - * Wait for the server to send the status, and return it. - * @return object The status object, with integer $code, string $details, - * and array $metadata members - */ - public function getStatus() { - $status_event = $this->completion_queue->pluck(FINISHED, - Timeval::inf_future()); - return $status_event->data; - } -} diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php index fde055a3b3..fc83dace20 100755 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -32,7 +32,6 @@ * */ namespace Grpc; -require_once realpath(dirname(__FILE__) . '/../autoload.php'); /** * Base class for generated client stubs. Stub methods are expected to call @@ -69,11 +68,9 @@ class BaseStub { $argument, callable $deserialize, $metadata = array()) { - return new SimpleSurfaceActiveCall($this->channel, - $method, - $deserialize, - $argument, - $metadata); + $call = new UnaryCall($this->channel, $method, $deserialize); + $call->start($argument, $metadata); + return $call; } /** @@ -91,11 +88,9 @@ class BaseStub { $arguments, callable $deserialize, $metadata = array()) { - return new ClientStreamingSurfaceActiveCall($this->channel, - $method, - $deserialize, - $arguments, - $metadata); + $call = new ClientStreamingCall($this->channel, $method, $deserialize); + $call->start($arguments, $metadata); + return $call; } /** @@ -112,11 +107,9 @@ class BaseStub { $argument, callable $deserialize, $metadata = array()) { - return new ServerStreamingSurfaceActiveCall($this->channel, - $method, - $deserialize, - $argument, - $metadata); + $call = new ServerStreamingCall($this->channel, $method, $deserialize); + $call->start($argument, $metadata); + return $call; } /** @@ -130,9 +123,8 @@ class BaseStub { public function _bidiRequest($method, callable $deserialize, $metadata = array()) { - return new BidiStreamingSurfaceActiveCall($this->channel, - $method, - $deserialize, - $metadata); + $call = new BidiStreamingCall($this->channel, $method, $deserialize); + $call->start($metadata); + return $call; } } diff --git a/src/php/lib/Grpc/AbstractSurfaceActiveCall.php b/src/php/lib/Grpc/BidiStreamingCall.php index 9d0af090ce..76c642bef4 100755..100644 --- a/src/php/lib/Grpc/AbstractSurfaceActiveCall.php +++ b/src/php/lib/Grpc/BidiStreamingCall.php @@ -1,5 +1,4 @@ <?php - /* * * Copyright 2015, Google Inc. @@ -32,67 +31,62 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - namespace Grpc; -require_once realpath(dirname(__FILE__) . '/../autoload.php'); - /** - * Represents an active call that allows sending and recieving messages. - * Subclasses restrict how data can be sent and recieved. + * Represents an active call that allows for sending and recieving messages in + * streams in any order. */ -abstract class AbstractSurfaceActiveCall { - private $active_call; - private $deserialize; - +class BidiStreamingCall extends AbstractCall { /** - * Create a new surface active call. - * @param Channel $channel The channel to communicate on - * @param string $method The method to call on the remote server - * @param callable $deserialize The function to deserialize a value + * Start the call * @param array $metadata Metadata to send with the call, if applicable - * @param long $flags Write flags to use with this call */ - public function __construct(Channel $channel, - $method, - callable $deserialize, - $metadata = array(), - $flags = 0) { - $this->active_call = new ActiveCall($channel, $method, $metadata, $flags); - $this->deserialize = $deserialize; + public function start($metadata) { + $this->call->startBatch([OP_SEND_INITIAL_METADATA => $metadata]); } /** - * @return The metadata sent by the server + * Reads the next value from the server. + * @return The next value from the server, or null if there is none */ - public function getMetadata() { - return $this->metadata(); + public function read() { + $batch = [OP_RECV_MESSAGE => true]; + if ($this->metadata === null) { + $batch[OP_RECV_INITIAL_METADATA] = true; + } + $read_event = $this->call->startBatch($batch); + if ($this->metadata === null) { + $this->metadata = $read_event->metadata; + } + return $this->deserializeResponse($read_event->message); } /** - * Cancels the call + * Write a single message to the server. This cannot be called after + * writesDone is called. + * @param ByteBuffer $data The data to write */ - public function cancel() { - $this->active_call->cancel(); + public function write($data) { + $this->call->startBatch([OP_SEND_MESSAGE => $data->serialize()]); } - protected function _read() { - $response = $this->active_call->read(); - if ($response === null) { - return null; - } - return call_user_func($this->deserialize, $response); - } - - protected function _write($value) { - return $this->active_call->write($value->serialize()); - } - - protected function _writesDone() { - $this->active_call->writesDone(); + /** + * Indicate that no more writes will be sent. + */ + public function writesDone() { + $this->call->startBatch([OP_SEND_CLOSE_FROM_CLIENT => true]); } - protected function _getStatus() { - return $this->active_call->getStatus(); + /** + * Wait for the server to send the status, and return it. + * @return object The status object, with integer $code, string $details, + * and array $metadata members + */ + public function getStatus() { + $status_event = $this->call->startBatch([ + OP_RECV_STATUS_ON_CLIENT => true + ]); + return $status_event->status; } -} +}
\ No newline at end of file diff --git a/src/php/lib/Grpc/ClientStreamingSurfaceActiveCall.php b/src/php/lib/Grpc/ClientStreamingCall.php index d33f09fbe4..61439d3f47 100755..100644 --- a/src/php/lib/Grpc/ClientStreamingSurfaceActiveCall.php +++ b/src/php/lib/Grpc/ClientStreamingCall.php @@ -32,31 +32,23 @@ * */ namespace Grpc; -require_once realpath(dirname(__FILE__) . '/../autoload.php'); /** * Represents an active call that sends a stream of messages and then gets a * single response. */ -class ClientStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall { +class ClientStreamingCall extends AbstractCall { /** - * Create a new simple (single request/single response) active call. - * @param Channel $channel The channel to communicate on - * @param string $method The method to call on the remote server - * @param callable $deserialize The function to deserialize a value + * Start the call. * @param Traversable $arg_iter The iterator of arguments to send * @param array $metadata Metadata to send with the call, if applicable */ - public function __construct(Channel $channel, - $method, - callable $deserialize, - $arg_iter, - $metadata = array()) { - parent::__construct($channel, $method, $deserialize, $metadata, 0); + public function start($arg_iter, $metadata = array()) { + $event = $this->call->startBatch([OP_SEND_INITIAL_METADATA => $metadata]); foreach($arg_iter as $arg) { - $this->_write($arg); + $this->call->startBatch([OP_SEND_MESSAGE => $arg->serialize()]); } - $this->_writesDone(); + $this->call->startBatch([OP_SEND_CLOSE_FROM_CLIENT => true]); } /** @@ -64,8 +56,11 @@ class ClientStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall { * @return [response data, status] */ public function wait() { - $response = $this->_read(); - $status = $this->_getStatus(); - return array($response, $status); + $event = $this->call->startBatch([ + OP_RECV_INITIAL_METADATA => true, + OP_RECV_MESSAGE => true, + OP_RECV_STATUS_ON_CLIENT => true]); + $this->metadata = $event->metadata; + return array($this->deserializeResponse($event->message), $event->status); } -} +}
\ No newline at end of file diff --git a/src/php/lib/Grpc/ServerStreamingSurfaceActiveCall.php b/src/php/lib/Grpc/ServerStreamingCall.php index fd08e86e51..631c863345 100755..100644 --- a/src/php/lib/Grpc/ServerStreamingSurfaceActiveCall.php +++ b/src/php/lib/Grpc/ServerStreamingCall.php @@ -33,42 +33,45 @@ */ namespace Grpc; -require_once realpath(dirname(__FILE__) . '/../autoload.php'); - /** * Represents an active call that sends a single message and then gets a stream * of reponses */ -class ServerStreamingSurfaceActiveCall extends AbstractSurfaceActiveCall { +class ServerStreamingCall extends AbstractCall { /** - * Create a new simple (single request/single response) active call. - * @param Channel $channel The channel to communicate on - * @param string $method The method to call on the remote server - * @param callable $deserialize The function to deserialize a value + * Start the call * @param $arg The argument to send * @param array $metadata Metadata to send with the call, if applicable */ - public function __construct(Channel $channel, - $method, - callable $deserialize, - $arg, - $metadata = array()) { - parent::__construct($channel, $method, $deserialize, $metadata, - \Grpc\WRITE_BUFFER_HINT); - $this->_write($arg); - $this->_writesDone(); + public function start($arg, $metadata = array()) { + $event = $this->call->startBatch([ + OP_SEND_INITIAL_METADATA => $metadata, + OP_RECV_INITIAL_METADATA => true, + OP_SEND_MESSAGE => $arg->serialize(), + OP_SEND_CLOSE_FROM_CLIENT => true]); + $this->metadata = $event->metadata; } /** * @return An iterator of response values */ public function responses() { - while(($response = $this->_read()) !== null) { - yield $response; + $response = $this->call->startBatch([OP_RECV_MESSAGE => true])->message; + while($response !== null) { + yield $this->deserializeResponse($response); + $response = $this->call->startBatch([OP_RECV_MESSAGE => true])->message; } } + /** + * Wait for the server to send the status, and return it. + * @return object The status object, with integer $code, string $details, + * and array $metadata members + */ public function getStatus() { - return $this->_getStatus(); + $status_event = $this->call->startBatch([ + OP_RECV_STATUS_ON_CLIENT => true + ]); + return $status_event->status; } -} +}
\ No newline at end of file diff --git a/src/php/lib/Grpc/SimpleSurfaceActiveCall.php b/src/php/lib/Grpc/UnaryCall.php index ba82f5704f..97a10a40f4 100755..100644 --- a/src/php/lib/Grpc/SimpleSurfaceActiveCall.php +++ b/src/php/lib/Grpc/UnaryCall.php @@ -33,30 +33,23 @@ */ namespace Grpc; -require_once realpath(dirname(__FILE__) . '/../autoload.php'); - /** * Represents an active call that sends a single message and then gets a single * response. */ -class SimpleSurfaceActiveCall extends AbstractSurfaceActiveCall { +class UnaryCall extends AbstractCall { /** - * Create a new simple (single request/single response) active call. - * @param Channel $channel The channel to communicate on - * @param string $method The method to call on the remote server - * @param callable $deserialize The function to deserialize a value + * Start the call * @param $arg The argument to send * @param array $metadata Metadata to send with the call, if applicable */ - public function __construct(Channel $channel, - $method, - callable $deserialize, - $arg, - $metadata = array()) { - parent::__construct($channel, $method, $deserialize, $metadata, - \Grpc\WRITE_BUFFER_HINT); - $this->_write($arg); - $this->_writesDone(); + public function start($arg, $metadata = array()) { + $event = $this->call->startBatch([ + OP_SEND_INITIAL_METADATA => $metadata, + OP_RECV_INITIAL_METADATA => true, + OP_SEND_MESSAGE => $arg->serialize(), + OP_SEND_CLOSE_FROM_CLIENT => true]); + $this->metadata = $event->metadata; } /** @@ -64,8 +57,9 @@ class SimpleSurfaceActiveCall extends AbstractSurfaceActiveCall { * @return [response data, status] */ public function wait() { - $response = $this->_read(); - $status = $this->_getStatus(); - return array($response, $status); + $event = $this->call->startBatch([ + OP_RECV_MESSAGE => true, + OP_RECV_STATUS_ON_CLIENT => true]); + return array($this->deserializeResponse($event->message), $event->status); } -} +}
\ No newline at end of file diff --git a/src/php/tests/generated_code/GeneratedCodeTest.php b/src/php/tests/generated_code/GeneratedCodeTest.php index cb2c0e6d10..927d24ca63 100755 --- a/src/php/tests/generated_code/GeneratedCodeTest.php +++ b/src/php/tests/generated_code/GeneratedCodeTest.php @@ -31,7 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -require_once realpath(dirname(__FILE__) . '/../../lib/autoload.php'); +require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php'); require 'DrSlump/Protobuf.php'; \DrSlump\Protobuf::autoload(); require 'math.php'; @@ -41,7 +41,8 @@ class GeneratedCodeTest extends PHPUnit_Framework_TestCase { protected static $client; protected static $timeout; public static function setUpBeforeClass() { - self::$client = new math\MathClient(getenv('GRPC_TEST_HOST')); + self::$client = new math\MathClient(new Grpc\BaseStub( + getenv('GRPC_TEST_HOST'), [])); } public function testSimpleRequest() { diff --git a/src/php/tests/generated_code/math.php b/src/php/tests/generated_code/math.php deleted file mode 100755 index e97a5cf97e..0000000000 --- a/src/php/tests/generated_code/math.php +++ /dev/null @@ -1,479 +0,0 @@ -<?php -// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0 -// Source: math.proto -// Date: 2014-11-14 00:00:41 - -namespace math { - - class DivArgs extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $dividend = null; - - /** @var int */ - public $divisor = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.DivArgs'); - - // REQUIRED INT64 dividend = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "dividend"; - $f->type = \DrSlump\Protobuf::TYPE_INT64; - $f->rule = \DrSlump\Protobuf::RULE_REQUIRED; - $descriptor->addField($f); - - // REQUIRED INT64 divisor = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "divisor"; - $f->type = \DrSlump\Protobuf::TYPE_INT64; - $f->rule = \DrSlump\Protobuf::RULE_REQUIRED; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <dividend> has a value - * - * @return boolean - */ - public function hasDividend(){ - return $this->_has(1); - } - - /** - * Clear <dividend> value - * - * @return \math\DivArgs - */ - public function clearDividend(){ - return $this->_clear(1); - } - - /** - * Get <dividend> value - * - * @return int - */ - public function getDividend(){ - return $this->_get(1); - } - - /** - * Set <dividend> value - * - * @param int $value - * @return \math\DivArgs - */ - public function setDividend( $value){ - return $this->_set(1, $value); - } - - /** - * Check if <divisor> has a value - * - * @return boolean - */ - public function hasDivisor(){ - return $this->_has(2); - } - - /** - * Clear <divisor> value - * - * @return \math\DivArgs - */ - public function clearDivisor(){ - return $this->_clear(2); - } - - /** - * Get <divisor> value - * - * @return int - */ - public function getDivisor(){ - return $this->_get(2); - } - - /** - * Set <divisor> value - * - * @param int $value - * @return \math\DivArgs - */ - public function setDivisor( $value){ - return $this->_set(2, $value); - } - } -} - -namespace math { - - class DivReply extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $quotient = null; - - /** @var int */ - public $remainder = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.DivReply'); - - // REQUIRED INT64 quotient = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "quotient"; - $f->type = \DrSlump\Protobuf::TYPE_INT64; - $f->rule = \DrSlump\Protobuf::RULE_REQUIRED; - $descriptor->addField($f); - - // REQUIRED INT64 remainder = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "remainder"; - $f->type = \DrSlump\Protobuf::TYPE_INT64; - $f->rule = \DrSlump\Protobuf::RULE_REQUIRED; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <quotient> has a value - * - * @return boolean - */ - public function hasQuotient(){ - return $this->_has(1); - } - - /** - * Clear <quotient> value - * - * @return \math\DivReply - */ - public function clearQuotient(){ - return $this->_clear(1); - } - - /** - * Get <quotient> value - * - * @return int - */ - public function getQuotient(){ - return $this->_get(1); - } - - /** - * Set <quotient> value - * - * @param int $value - * @return \math\DivReply - */ - public function setQuotient( $value){ - return $this->_set(1, $value); - } - - /** - * Check if <remainder> has a value - * - * @return boolean - */ - public function hasRemainder(){ - return $this->_has(2); - } - - /** - * Clear <remainder> value - * - * @return \math\DivReply - */ - public function clearRemainder(){ - return $this->_clear(2); - } - - /** - * Get <remainder> value - * - * @return int - */ - public function getRemainder(){ - return $this->_get(2); - } - - /** - * Set <remainder> value - * - * @param int $value - * @return \math\DivReply - */ - public function setRemainder( $value){ - return $this->_set(2, $value); - } - } -} - -namespace math { - - class FibArgs extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $limit = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.FibArgs'); - - // OPTIONAL INT64 limit = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "limit"; - $f->type = \DrSlump\Protobuf::TYPE_INT64; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <limit> has a value - * - * @return boolean - */ - public function hasLimit(){ - return $this->_has(1); - } - - /** - * Clear <limit> value - * - * @return \math\FibArgs - */ - public function clearLimit(){ - return $this->_clear(1); - } - - /** - * Get <limit> value - * - * @return int - */ - public function getLimit(){ - return $this->_get(1); - } - - /** - * Set <limit> value - * - * @param int $value - * @return \math\FibArgs - */ - public function setLimit( $value){ - return $this->_set(1, $value); - } - } -} - -namespace math { - - class Num extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $num = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.Num'); - - // REQUIRED INT64 num = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "num"; - $f->type = \DrSlump\Protobuf::TYPE_INT64; - $f->rule = \DrSlump\Protobuf::RULE_REQUIRED; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <num> has a value - * - * @return boolean - */ - public function hasNum(){ - return $this->_has(1); - } - - /** - * Clear <num> value - * - * @return \math\Num - */ - public function clearNum(){ - return $this->_clear(1); - } - - /** - * Get <num> value - * - * @return int - */ - public function getNum(){ - return $this->_get(1); - } - - /** - * Set <num> value - * - * @param int $value - * @return \math\Num - */ - public function setNum( $value){ - return $this->_set(1, $value); - } - } -} - -namespace math { - - class FibReply extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $count = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'math.FibReply'); - - // REQUIRED INT64 count = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "count"; - $f->type = \DrSlump\Protobuf::TYPE_INT64; - $f->rule = \DrSlump\Protobuf::RULE_REQUIRED; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <count> has a value - * - * @return boolean - */ - public function hasCount(){ - return $this->_has(1); - } - - /** - * Clear <count> value - * - * @return \math\FibReply - */ - public function clearCount(){ - return $this->_clear(1); - } - - /** - * Get <count> value - * - * @return int - */ - public function getCount(){ - return $this->_get(1); - } - - /** - * Set <count> value - * - * @param int $value - * @return \math\FibReply - */ - public function setCount( $value){ - return $this->_set(1, $value); - } - } -} - -namespace math { - - class MathClient extends \Grpc\BaseStub { - /** - * @param math\DivArgs $input - * @return math\DivReply - */ - public function Div(\math\DivArgs $argument, $metadata = array()) { - return $this->_simpleRequest('/Math/Div', $argument, '\math\DivReply::deserialize', $metadata); - } - /** - * @param math\DivArgs $input - * @return math\DivReply - */ - public function DivMany($metadata = array()) { - return $this->_bidiRequest('/Math/DivMany', '\math\DivReply::deserialize', $metadata); - } - /** - * @param math\FibArgs $input - * @return math\Num - */ - public function Fib($argument, $metadata = array()) { - return $this->_serverStreamRequest('/Math/Fib', $argument, '\math\Num::deserialize', $metadata); - } - /** - * @param math\Num $input - * @return math\Num - */ - public function Sum($arguments, $metadata = array()) { - return $this->_clientStreamRequest('/Math/Sum', $arguments, '\math\Num::deserialize', $metadata); - } - } -} diff --git a/src/php/tests/generated_code/math.proto b/src/php/tests/generated_code/math.proto new file mode 100644 index 0000000000..e34ad5e967 --- /dev/null +++ b/src/php/tests/generated_code/math.proto @@ -0,0 +1,80 @@ + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +package math; + +message DivArgs { + optional int64 dividend = 1; + optional int64 divisor = 2; +} + +message DivReply { + optional int64 quotient = 1; + optional int64 remainder = 2; +} + +message FibArgs { + optional int64 limit = 1; +} + +message Num { + optional int64 num = 1; +} + +message FibReply { + optional int64 count = 1; +} + +service Math { + // Div divides args.dividend by args.divisor and returns the quotient and + // remainder. + rpc Div (DivArgs) returns (DivReply) { + } + + // DivMany accepts an arbitrary number of division args from the client stream + // and sends back the results in the reply stream. The stream continues until + // the client closes its end; the server does the same after sending all the + // replies. The stream ends immediately if either end aborts. + rpc DivMany (stream DivArgs) returns (stream DivReply) { + } + + // Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib + // generates up to limit numbers; otherwise it continues until the call is + // canceled. Unlike Fib above, Fib has no final FibReply. + rpc Fib (FibArgs) returns (stream Num) { + } + + // Sum sums a stream of numbers, returning the final result once the stream + // is closed. + rpc Sum (stream Num) returns (Num) { + } +} diff --git a/src/php/tests/interop/empty.php b/src/php/tests/interop/empty.php deleted file mode 100755 index 22b11803b6..0000000000 --- a/src/php/tests/interop/empty.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php -// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0 -// Source: test/cpp/interop/empty.proto -// Date: 2015-01-30 23:30:46 - -namespace grpc\testing { - - class EmptyMessage extends \DrSlump\Protobuf\Message { - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.EmptyMessage'); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - } -} diff --git a/src/php/tests/interop/empty.proto b/src/php/tests/interop/empty.proto new file mode 100644 index 0000000000..4200d7b519 --- /dev/null +++ b/src/php/tests/interop/empty.proto @@ -0,0 +1,43 @@ + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto2"; + +package grpc.testing; + +// An empty message that you can re-use to avoid defining duplicated empty +// messages in your project. A typical example is to use it as argument or the +// return value of a service API. For instance: +// +// service Foo { +// rpc Bar (grpc.testing.EmptyMessage) returns (grpc.testing.EmptyMessage) { }; +// }; +// +message EmptyMessage {} diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 82ca438169..6f81bfa6cd 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -31,7 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ -require_once realpath(dirname(__FILE__) . '/../../lib/autoload.php'); +require_once realpath(dirname(__FILE__) . '/../../vendor/autoload.php'); require 'DrSlump/Protobuf.php'; \DrSlump\Protobuf::autoload(); require 'empty.php'; @@ -132,8 +132,6 @@ function serverStreaming($stub) { } $call = $stub->StreamingOutputCall($request); - hardAssert($call->getStatus()->code === Grpc\STATUS_OK, - 'Call did not complete successfully'); $i = 0; foreach($call->responses() as $value) { hardAssert($i < 4, 'Too many responses'); @@ -142,7 +140,10 @@ function serverStreaming($stub) { 'Payload ' . $i . ' had the wrong type'); hardAssert(strlen($payload->getBody()) === $sizes[$i], 'Response ' . $i . ' had the wrong length'); + $i += 1; } + hardAssert($call->getStatus()->code === Grpc\STATUS_OK, + 'Call did not complete successfully'); } /** @@ -240,4 +241,7 @@ switch($args['test_case']) { break; case 'cancel_after_first_response': cancelAfterFirstResponse($stub); + break; + default: + exit(1); } diff --git a/src/php/tests/interop/messages.php b/src/php/tests/interop/messages.php deleted file mode 100755 index a626a17ab3..0000000000 --- a/src/php/tests/interop/messages.php +++ /dev/null @@ -1,1074 +0,0 @@ -<?php -// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0 -// Source: test/cpp/interop/messages.proto -// Date: 2015-01-30 23:30:46 - -namespace grpc\testing { - - class PayloadType extends \DrSlump\Protobuf\Enum { - const COMPRESSABLE = 0; - const UNCOMPRESSABLE = 1; - const RANDOM = 2; - } -} -namespace grpc\testing { - - class Payload extends \DrSlump\Protobuf\Message { - - /** @var int - \grpc\testing\PayloadType */ - public $type = null; - - /** @var string */ - public $body = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.Payload'); - - // OPTIONAL ENUM type = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "type"; - $f->type = \DrSlump\Protobuf::TYPE_ENUM; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\PayloadType'; - $descriptor->addField($f); - - // OPTIONAL BYTES body = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "body"; - $f->type = \DrSlump\Protobuf::TYPE_BYTES; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <type> has a value - * - * @return boolean - */ - public function hasType(){ - return $this->_has(1); - } - - /** - * Clear <type> value - * - * @return \grpc\testing\Payload - */ - public function clearType(){ - return $this->_clear(1); - } - - /** - * Get <type> value - * - * @return int - \grpc\testing\PayloadType - */ - public function getType(){ - return $this->_get(1); - } - - /** - * Set <type> value - * - * @param int - \grpc\testing\PayloadType $value - * @return \grpc\testing\Payload - */ - public function setType( $value){ - return $this->_set(1, $value); - } - - /** - * Check if <body> has a value - * - * @return boolean - */ - public function hasBody(){ - return $this->_has(2); - } - - /** - * Clear <body> value - * - * @return \grpc\testing\Payload - */ - public function clearBody(){ - return $this->_clear(2); - } - - /** - * Get <body> value - * - * @return string - */ - public function getBody(){ - return $this->_get(2); - } - - /** - * Set <body> value - * - * @param string $value - * @return \grpc\testing\Payload - */ - public function setBody( $value){ - return $this->_set(2, $value); - } - } -} - -namespace grpc\testing { - - class SimpleRequest extends \DrSlump\Protobuf\Message { - - /** @var int - \grpc\testing\PayloadType */ - public $response_type = null; - - /** @var int */ - public $response_size = null; - - /** @var \grpc\testing\Payload */ - public $payload = null; - - /** @var boolean */ - public $fill_username = null; - - /** @var boolean */ - public $fill_oauth_scope = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.SimpleRequest'); - - // OPTIONAL ENUM response_type = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "response_type"; - $f->type = \DrSlump\Protobuf::TYPE_ENUM; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\PayloadType'; - $descriptor->addField($f); - - // OPTIONAL INT32 response_size = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "response_size"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - // OPTIONAL MESSAGE payload = 3 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 3; - $f->name = "payload"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\Payload'; - $descriptor->addField($f); - - // OPTIONAL BOOL fill_username = 4 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 4; - $f->name = "fill_username"; - $f->type = \DrSlump\Protobuf::TYPE_BOOL; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - // OPTIONAL BOOL fill_oauth_scope = 5 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 5; - $f->name = "fill_oauth_scope"; - $f->type = \DrSlump\Protobuf::TYPE_BOOL; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <response_type> has a value - * - * @return boolean - */ - public function hasResponseType(){ - return $this->_has(1); - } - - /** - * Clear <response_type> value - * - * @return \grpc\testing\SimpleRequest - */ - public function clearResponseType(){ - return $this->_clear(1); - } - - /** - * Get <response_type> value - * - * @return int - \grpc\testing\PayloadType - */ - public function getResponseType(){ - return $this->_get(1); - } - - /** - * Set <response_type> value - * - * @param int - \grpc\testing\PayloadType $value - * @return \grpc\testing\SimpleRequest - */ - public function setResponseType( $value){ - return $this->_set(1, $value); - } - - /** - * Check if <response_size> has a value - * - * @return boolean - */ - public function hasResponseSize(){ - return $this->_has(2); - } - - /** - * Clear <response_size> value - * - * @return \grpc\testing\SimpleRequest - */ - public function clearResponseSize(){ - return $this->_clear(2); - } - - /** - * Get <response_size> value - * - * @return int - */ - public function getResponseSize(){ - return $this->_get(2); - } - - /** - * Set <response_size> value - * - * @param int $value - * @return \grpc\testing\SimpleRequest - */ - public function setResponseSize( $value){ - return $this->_set(2, $value); - } - - /** - * Check if <payload> has a value - * - * @return boolean - */ - public function hasPayload(){ - return $this->_has(3); - } - - /** - * Clear <payload> value - * - * @return \grpc\testing\SimpleRequest - */ - public function clearPayload(){ - return $this->_clear(3); - } - - /** - * Get <payload> value - * - * @return \grpc\testing\Payload - */ - public function getPayload(){ - return $this->_get(3); - } - - /** - * Set <payload> value - * - * @param \grpc\testing\Payload $value - * @return \grpc\testing\SimpleRequest - */ - public function setPayload(\grpc\testing\Payload $value){ - return $this->_set(3, $value); - } - - /** - * Check if <fill_username> has a value - * - * @return boolean - */ - public function hasFillUsername(){ - return $this->_has(4); - } - - /** - * Clear <fill_username> value - * - * @return \grpc\testing\SimpleRequest - */ - public function clearFillUsername(){ - return $this->_clear(4); - } - - /** - * Get <fill_username> value - * - * @return boolean - */ - public function getFillUsername(){ - return $this->_get(4); - } - - /** - * Set <fill_username> value - * - * @param boolean $value - * @return \grpc\testing\SimpleRequest - */ - public function setFillUsername( $value){ - return $this->_set(4, $value); - } - - /** - * Check if <fill_oauth_scope> has a value - * - * @return boolean - */ - public function hasFillOauthScope(){ - return $this->_has(5); - } - - /** - * Clear <fill_oauth_scope> value - * - * @return \grpc\testing\SimpleRequest - */ - public function clearFillOauthScope(){ - return $this->_clear(5); - } - - /** - * Get <fill_oauth_scope> value - * - * @return boolean - */ - public function getFillOauthScope(){ - return $this->_get(5); - } - - /** - * Set <fill_oauth_scope> value - * - * @param boolean $value - * @return \grpc\testing\SimpleRequest - */ - public function setFillOauthScope( $value){ - return $this->_set(5, $value); - } - } -} - -namespace grpc\testing { - - class SimpleResponse extends \DrSlump\Protobuf\Message { - - /** @var \grpc\testing\Payload */ - public $payload = null; - - /** @var string */ - public $username = null; - - /** @var string */ - public $oauth_scope = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.SimpleResponse'); - - // OPTIONAL MESSAGE payload = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "payload"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\Payload'; - $descriptor->addField($f); - - // OPTIONAL STRING username = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "username"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - // OPTIONAL STRING oauth_scope = 3 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 3; - $f->name = "oauth_scope"; - $f->type = \DrSlump\Protobuf::TYPE_STRING; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <payload> has a value - * - * @return boolean - */ - public function hasPayload(){ - return $this->_has(1); - } - - /** - * Clear <payload> value - * - * @return \grpc\testing\SimpleResponse - */ - public function clearPayload(){ - return $this->_clear(1); - } - - /** - * Get <payload> value - * - * @return \grpc\testing\Payload - */ - public function getPayload(){ - return $this->_get(1); - } - - /** - * Set <payload> value - * - * @param \grpc\testing\Payload $value - * @return \grpc\testing\SimpleResponse - */ - public function setPayload(\grpc\testing\Payload $value){ - return $this->_set(1, $value); - } - - /** - * Check if <username> has a value - * - * @return boolean - */ - public function hasUsername(){ - return $this->_has(2); - } - - /** - * Clear <username> value - * - * @return \grpc\testing\SimpleResponse - */ - public function clearUsername(){ - return $this->_clear(2); - } - - /** - * Get <username> value - * - * @return string - */ - public function getUsername(){ - return $this->_get(2); - } - - /** - * Set <username> value - * - * @param string $value - * @return \grpc\testing\SimpleResponse - */ - public function setUsername( $value){ - return $this->_set(2, $value); - } - - /** - * Check if <oauth_scope> has a value - * - * @return boolean - */ - public function hasOauthScope(){ - return $this->_has(3); - } - - /** - * Clear <oauth_scope> value - * - * @return \grpc\testing\SimpleResponse - */ - public function clearOauthScope(){ - return $this->_clear(3); - } - - /** - * Get <oauth_scope> value - * - * @return string - */ - public function getOauthScope(){ - return $this->_get(3); - } - - /** - * Set <oauth_scope> value - * - * @param string $value - * @return \grpc\testing\SimpleResponse - */ - public function setOauthScope( $value){ - return $this->_set(3, $value); - } - } -} - -namespace grpc\testing { - - class StreamingInputCallRequest extends \DrSlump\Protobuf\Message { - - /** @var \grpc\testing\Payload */ - public $payload = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingInputCallRequest'); - - // OPTIONAL MESSAGE payload = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "payload"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\Payload'; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <payload> has a value - * - * @return boolean - */ - public function hasPayload(){ - return $this->_has(1); - } - - /** - * Clear <payload> value - * - * @return \grpc\testing\StreamingInputCallRequest - */ - public function clearPayload(){ - return $this->_clear(1); - } - - /** - * Get <payload> value - * - * @return \grpc\testing\Payload - */ - public function getPayload(){ - return $this->_get(1); - } - - /** - * Set <payload> value - * - * @param \grpc\testing\Payload $value - * @return \grpc\testing\StreamingInputCallRequest - */ - public function setPayload(\grpc\testing\Payload $value){ - return $this->_set(1, $value); - } - } -} - -namespace grpc\testing { - - class StreamingInputCallResponse extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $aggregated_payload_size = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingInputCallResponse'); - - // OPTIONAL INT32 aggregated_payload_size = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "aggregated_payload_size"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <aggregated_payload_size> has a value - * - * @return boolean - */ - public function hasAggregatedPayloadSize(){ - return $this->_has(1); - } - - /** - * Clear <aggregated_payload_size> value - * - * @return \grpc\testing\StreamingInputCallResponse - */ - public function clearAggregatedPayloadSize(){ - return $this->_clear(1); - } - - /** - * Get <aggregated_payload_size> value - * - * @return int - */ - public function getAggregatedPayloadSize(){ - return $this->_get(1); - } - - /** - * Set <aggregated_payload_size> value - * - * @param int $value - * @return \grpc\testing\StreamingInputCallResponse - */ - public function setAggregatedPayloadSize( $value){ - return $this->_set(1, $value); - } - } -} - -namespace grpc\testing { - - class ResponseParameters extends \DrSlump\Protobuf\Message { - - /** @var int */ - public $size = null; - - /** @var int */ - public $interval_us = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.ResponseParameters'); - - // OPTIONAL INT32 size = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "size"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - // OPTIONAL INT32 interval_us = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "interval_us"; - $f->type = \DrSlump\Protobuf::TYPE_INT32; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <size> has a value - * - * @return boolean - */ - public function hasSize(){ - return $this->_has(1); - } - - /** - * Clear <size> value - * - * @return \grpc\testing\ResponseParameters - */ - public function clearSize(){ - return $this->_clear(1); - } - - /** - * Get <size> value - * - * @return int - */ - public function getSize(){ - return $this->_get(1); - } - - /** - * Set <size> value - * - * @param int $value - * @return \grpc\testing\ResponseParameters - */ - public function setSize( $value){ - return $this->_set(1, $value); - } - - /** - * Check if <interval_us> has a value - * - * @return boolean - */ - public function hasIntervalUs(){ - return $this->_has(2); - } - - /** - * Clear <interval_us> value - * - * @return \grpc\testing\ResponseParameters - */ - public function clearIntervalUs(){ - return $this->_clear(2); - } - - /** - * Get <interval_us> value - * - * @return int - */ - public function getIntervalUs(){ - return $this->_get(2); - } - - /** - * Set <interval_us> value - * - * @param int $value - * @return \grpc\testing\ResponseParameters - */ - public function setIntervalUs( $value){ - return $this->_set(2, $value); - } - } -} - -namespace grpc\testing { - - class StreamingOutputCallRequest extends \DrSlump\Protobuf\Message { - - /** @var int - \grpc\testing\PayloadType */ - public $response_type = null; - - /** @var \grpc\testing\ResponseParameters[] */ - public $response_parameters = array(); - - /** @var \grpc\testing\Payload */ - public $payload = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingOutputCallRequest'); - - // OPTIONAL ENUM response_type = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "response_type"; - $f->type = \DrSlump\Protobuf::TYPE_ENUM; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\PayloadType'; - $descriptor->addField($f); - - // REPEATED MESSAGE response_parameters = 2 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 2; - $f->name = "response_parameters"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_REPEATED; - $f->reference = '\grpc\testing\ResponseParameters'; - $descriptor->addField($f); - - // OPTIONAL MESSAGE payload = 3 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 3; - $f->name = "payload"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\Payload'; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <response_type> has a value - * - * @return boolean - */ - public function hasResponseType(){ - return $this->_has(1); - } - - /** - * Clear <response_type> value - * - * @return \grpc\testing\StreamingOutputCallRequest - */ - public function clearResponseType(){ - return $this->_clear(1); - } - - /** - * Get <response_type> value - * - * @return int - \grpc\testing\PayloadType - */ - public function getResponseType(){ - return $this->_get(1); - } - - /** - * Set <response_type> value - * - * @param int - \grpc\testing\PayloadType $value - * @return \grpc\testing\StreamingOutputCallRequest - */ - public function setResponseType( $value){ - return $this->_set(1, $value); - } - - /** - * Check if <response_parameters> has a value - * - * @return boolean - */ - public function hasResponseParameters(){ - return $this->_has(2); - } - - /** - * Clear <response_parameters> value - * - * @return \grpc\testing\StreamingOutputCallRequest - */ - public function clearResponseParameters(){ - return $this->_clear(2); - } - - /** - * Get <response_parameters> value - * - * @param int $idx - * @return \grpc\testing\ResponseParameters - */ - public function getResponseParameters($idx = NULL){ - return $this->_get(2, $idx); - } - - /** - * Set <response_parameters> value - * - * @param \grpc\testing\ResponseParameters $value - * @return \grpc\testing\StreamingOutputCallRequest - */ - public function setResponseParameters(\grpc\testing\ResponseParameters $value, $idx = NULL){ - return $this->_set(2, $value, $idx); - } - - /** - * Get all elements of <response_parameters> - * - * @return \grpc\testing\ResponseParameters[] - */ - public function getResponseParametersList(){ - return $this->_get(2); - } - - /** - * Add a new element to <response_parameters> - * - * @param \grpc\testing\ResponseParameters $value - * @return \grpc\testing\StreamingOutputCallRequest - */ - public function addResponseParameters(\grpc\testing\ResponseParameters $value){ - return $this->_add(2, $value); - } - - /** - * Check if <payload> has a value - * - * @return boolean - */ - public function hasPayload(){ - return $this->_has(3); - } - - /** - * Clear <payload> value - * - * @return \grpc\testing\StreamingOutputCallRequest - */ - public function clearPayload(){ - return $this->_clear(3); - } - - /** - * Get <payload> value - * - * @return \grpc\testing\Payload - */ - public function getPayload(){ - return $this->_get(3); - } - - /** - * Set <payload> value - * - * @param \grpc\testing\Payload $value - * @return \grpc\testing\StreamingOutputCallRequest - */ - public function setPayload(\grpc\testing\Payload $value){ - return $this->_set(3, $value); - } - } -} - -namespace grpc\testing { - - class StreamingOutputCallResponse extends \DrSlump\Protobuf\Message { - - /** @var \grpc\testing\Payload */ - public $payload = null; - - - /** @var \Closure[] */ - protected static $__extensions = array(); - - public static function descriptor() - { - $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'grpc.testing.StreamingOutputCallResponse'); - - // OPTIONAL MESSAGE payload = 1 - $f = new \DrSlump\Protobuf\Field(); - $f->number = 1; - $f->name = "payload"; - $f->type = \DrSlump\Protobuf::TYPE_MESSAGE; - $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL; - $f->reference = '\grpc\testing\Payload'; - $descriptor->addField($f); - - foreach (self::$__extensions as $cb) { - $descriptor->addField($cb(), true); - } - - return $descriptor; - } - - /** - * Check if <payload> has a value - * - * @return boolean - */ - public function hasPayload(){ - return $this->_has(1); - } - - /** - * Clear <payload> value - * - * @return \grpc\testing\StreamingOutputCallResponse - */ - public function clearPayload(){ - return $this->_clear(1); - } - - /** - * Get <payload> value - * - * @return \grpc\testing\Payload - */ - public function getPayload(){ - return $this->_get(1); - } - - /** - * Set <payload> value - * - * @param \grpc\testing\Payload $value - * @return \grpc\testing\StreamingOutputCallResponse - */ - public function setPayload(\grpc\testing\Payload $value){ - return $this->_set(1, $value); - } - } -} - diff --git a/src/php/tests/interop/messages.proto b/src/php/tests/interop/messages.proto new file mode 100644 index 0000000000..de0b1a2320 --- /dev/null +++ b/src/php/tests/interop/messages.proto @@ -0,0 +1,132 @@ + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Message definitions to be used by integration test service definitions. + +syntax = "proto2"; + +package grpc.testing; + +// The type of payload that should be returned. +enum PayloadType { + // Compressable text format. + COMPRESSABLE = 0; + + // Uncompressable binary format. + UNCOMPRESSABLE = 1; + + // Randomly chosen from all other formats defined in this enum. + RANDOM = 2; +} + +// A block of data, to simply increase gRPC message size. +message Payload { + // The type of data in body. + optional PayloadType type = 1 [default = COMPRESSABLE]; + // Primary contents of payload. + optional bytes body = 2; +} + +// Unary request. +message SimpleRequest { + // Desired payload type in the response from the server. + // If response_type is RANDOM, server randomly chooses one from other formats. + optional PayloadType response_type = 1 [default = COMPRESSABLE]; + + // Desired payload size in the response from the server. + // If response_type is COMPRESSABLE, this denotes the size before compression. + optional int32 response_size = 2; + + // Optional input payload sent along with the request. + optional Payload payload = 3; + + // Whether SimpleResponse should include username. + optional bool fill_username = 4; + + // Whether SimpleResponse should include OAuth scope. + optional bool fill_oauth_scope = 5; +} + +// Unary response, as configured by the request. +message SimpleResponse { + // Payload to increase message size. + optional Payload payload = 1; + // The user the request came from, for verifying authentication was + // successful when the client expected it. + optional string username = 2; + // OAuth scope. + optional string oauth_scope = 3; +} + +// Client-streaming request. +message StreamingInputCallRequest { + // Optional input payload sent along with the request. + optional Payload payload = 1; + + // Not expecting any payload from the response. +} + +// Client-streaming response. +message StreamingInputCallResponse { + // Aggregated size of payloads received from the client. + optional int32 aggregated_payload_size = 1; +} + +// Configuration for a particular response. +message ResponseParameters { + // Desired payload sizes in responses from the server. + // If response_type is COMPRESSABLE, this denotes the size before compression. + optional int32 size = 1; + + // Desired interval between consecutive responses in the response stream in + // microseconds. + optional int32 interval_us = 2; +} + +// Server-streaming request. +message StreamingOutputCallRequest { + // Desired payload type in the response from the server. + // If response_type is RANDOM, the payload from each response in the stream + // might be of different types. This is to simulate a mixed type of payload + // stream. + optional PayloadType response_type = 1 [default = COMPRESSABLE]; + + // Configuration for each expected response message. + repeated ResponseParameters response_parameters = 2; + + // Optional input payload sent along with the request. + optional Payload payload = 3; +} + +// Server-streaming response, as configured by the request and parameters. +message StreamingOutputCallResponse { + // Payload to increase response size. + optional Payload payload = 1; +} diff --git a/src/php/tests/interop/test.php b/src/php/tests/interop/test.php deleted file mode 100755 index 014bbc9517..0000000000 --- a/src/php/tests/interop/test.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0 -// Source: test/cpp/interop/test.proto -// Date: 2015-01-30 23:30:46 - -namespace grpc\testing { - - class TestServiceClient{ - - private $rpc_impl; - - public function __construct($rpc_impl) { - $this->rpc_impl = $rpc_impl; - } - /** - * @param grpc\testing\EmptyMessage $input - */ - public function EmptyCall(\grpc\testing\EmptyMessage $argument, $metadata = array()) { - return $this->rpc_impl->_simpleRequest('/grpc.testing.TestService/EmptyCall', $argument, '\grpc\testing\EmptyMessage::deserialize', $metadata); - } - /** - * @param grpc\testing\SimpleRequest $input - */ - public function UnaryCall(\grpc\testing\SimpleRequest $argument, $metadata = array()) { - return $this->rpc_impl->_simpleRequest('/grpc.testing.TestService/UnaryCall', $argument, '\grpc\testing\SimpleResponse::deserialize', $metadata); - } - /** - * @param grpc\testing\StreamingOutputCallRequest $input - */ - public function StreamingOutputCall($argument, $metadata = array()) { - return $this->rpc_impl->_serverStreamRequest('/grpc.testing.TestService/StreamingOutputCall', $argument, '\grpc\testing\StreamingOutputCallResponse::deserialize', $metadata); - } - /** - * @param grpc\testing\StreamingInputCallRequest $input - */ - public function StreamingInputCall($arguments, $metadata = array()) { - return $this->rpc_impl->_clientStreamRequest('/grpc.testing.TestService/StreamingInputCall', $arguments, '\grpc\testing\StreamingInputCallResponse::deserialize', $metadata); - } - /** - * @param grpc\testing\StreamingOutputCallRequest $input - */ - public function FullDuplexCall($metadata = array()) { - return $this->rpc_impl->_bidiRequest('/grpc.testing.TestService/FullDuplexCall', '\grpc\testing\StreamingOutputCallResponse::deserialize', $metadata); - } - /** - * @param grpc\testing\StreamingOutputCallRequest $input - */ - public function HalfDuplexCall($metadata = array()) { - return $this->rpc_impl->_bidiRequest('/grpc.testing.TestService/HalfDuplexCall', '\grpc\testing\StreamingOutputCallResponse::deserialize', $metadata); - } - } -} diff --git a/src/php/tests/interop/test.proto b/src/php/tests/interop/test.proto new file mode 100644 index 0000000000..39c08f3544 --- /dev/null +++ b/src/php/tests/interop/test.proto @@ -0,0 +1,72 @@ + +// 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. + +// An integration test service that covers all the method signature permutations +// of unary/streaming requests/responses. +syntax = "proto2"; + +import "empty.proto"; +import "messages.proto"; + +package grpc.testing; + +// A simple service to test the various types of RPCs and experiment with +// performance with various types of payload. +service TestService { + // One empty request followed by one empty response. + rpc EmptyCall(grpc.testing.EmptyMessage) returns (grpc.testing.EmptyMessage); + + // One request followed by one response. + // TODO(Issue 527): Describe required server behavior. + rpc UnaryCall(SimpleRequest) returns (SimpleResponse); + + // One request followed by a sequence of responses (streamed download). + // The server returns the payload with client desired type and sizes. + rpc StreamingOutputCall(StreamingOutputCallRequest) + returns (stream StreamingOutputCallResponse); + + // A sequence of requests followed by one response (streamed upload). + // The server returns the aggregated size of client payload as the result. + rpc StreamingInputCall(stream StreamingInputCallRequest) + returns (StreamingInputCallResponse); + + // A sequence of requests with each request served by the server immediately. + // As one request could lead to multiple responses, this interface + // demonstrates the idea of full duplexing. + rpc FullDuplexCall(stream StreamingOutputCallRequest) + returns (stream StreamingOutputCallResponse); + + // A sequence of requests followed by a sequence of responses. + // The server buffers all the client requests and then serves them in order. A + // stream of responses are returned to the client when the server starts with + // first request. + rpc HalfDuplexCall(stream StreamingOutputCallRequest) + returns (stream StreamingOutputCallResponse); +} diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php index 8bb0927f21..77a2d86ce4 100755 --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -36,65 +36,47 @@ class CallTest extends PHPUnit_Framework_TestCase{ static $port; public static function setUpBeforeClass() { - $cq = new Grpc\CompletionQueue(); - self::$server = new Grpc\Server($cq, []); - self::$port = self::$server->add_http2_port('0.0.0.0:0'); + self::$server = new Grpc\Server([]); + self::$port = self::$server->addHttp2Port('0.0.0.0:0'); } public function setUp() { - $this->cq = new Grpc\CompletionQueue(); $this->channel = new Grpc\Channel('localhost:' . self::$port, []); $this->call = new Grpc\Call($this->channel, '/foo', - Grpc\Timeval::inf_future()); + Grpc\Timeval::infFuture()); } - /** - * @expectedException LogicException - * @expectedExceptionCode Grpc\CALL_ERROR_INVALID_FLAGS - * @expectedExceptionMessage invoke - */ - public function testInvokeRejectsBadFlags() { - $this->call->invoke($this->cq, 0, 0, 0xDEADBEEF); - } - - /** - * @expectedException LogicException - * @expectedExceptionCode Grpc\CALL_ERROR_NOT_ON_CLIENT - * @expectedExceptionMessage server_accept - */ - public function testServerAcceptFailsCorrectly() { - $this->call->server_accept($this->cq, 0); - } - - /* These test methods with assertTrue(true) at the end just check that the - method calls completed without errors. PHPUnit warns for tests with no - asserts, and this avoids that warning without changing the meaning of the - tests */ - public function testAddEmptyMetadata() { - $this->call->add_metadata([], 0); - /* Dummy assert: Checks that the previous call completed without error */ - $this->assertTrue(true); + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => [] + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); } public function testAddSingleMetadata() { - $this->call->add_metadata(['key' => ['value']], 0); - /* Dummy assert: Checks that the previous call completed without error */ - $this->assertTrue(true); + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value']] + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); } public function testAddMultiValueMetadata() { - $this->call->add_metadata(['key' => ['value1', 'value2']], 0); - /* Dummy assert: Checks that the previous call completed without error */ - $this->assertTrue(true); + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key' => ['value1', 'value2']] + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); } public function testAddSingleAndMultiValueMetadata() { - $this->call->add_metadata( - ['key1' => ['value1'], - 'key2' => ['value2', 'value3']], 0); - /* Dummy assert: Checks that the previous call completed without error */ - $this->assertTrue(true); + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], + 'key2' => ['value2', 'value3']] + ]; + $result = $this->call->startBatch($batch); + $this->assertTrue($result->send_metadata); } } diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php index 0cbc506c8e..296873fa8f 100755 --- a/src/php/tests/unit_tests/EndToEndTest.php +++ b/src/php/tests/unit_tests/EndToEndTest.php @@ -33,81 +33,68 @@ */ class EndToEndTest extends PHPUnit_Framework_TestCase{ public function setUp() { - $this->client_queue = new Grpc\CompletionQueue(); - $this->server_queue = new Grpc\CompletionQueue(); - $this->server = new Grpc\Server($this->server_queue, []); - $port = $this->server->add_http2_port('0.0.0.0:0'); + $this->server = new Grpc\Server([]); + $port = $this->server->addHttp2Port('0.0.0.0:0'); $this->channel = new Grpc\Channel('localhost:' . $port, []); + $this->server->start(); } public function tearDown() { unset($this->channel); unset($this->server); - unset($this->client_queue); - unset($this->server_queue); } public function testSimpleRequestBody() { - $deadline = Grpc\Timeval::inf_future(); + $deadline = Grpc\Timeval::infFuture(); $status_text = 'xyz'; $call = new Grpc\Call($this->channel, 'dummy_method', $deadline); - $tag = 1; - $call->invoke($this->client_queue, $tag, $tag); - $server_tag = 2; - - $call->writes_done($tag); - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); - - // check that a server rpc new was received - $this->server->start(); - $this->server->request_call($server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type); - $server_call = $event->call; - $this->assertNotNull($server_call); - $server_call->server_accept($this->server_queue, $server_tag); - - $server_call->server_end_initial_metadata(); + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true + ]); - // the server sends the status - $server_call->start_write_status(Grpc\STATUS_OK, $status_text, $server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_close); - // the client gets CLIENT_METADATA_READ - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type); + $event = $this->server->requestCall(); + $this->assertSame('dummy_method', $event->method); + $this->assertSame([], $event->metadata); + $server_call = $event->call; - // the client gets FINISHED - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - $status = $event->data; + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_status); + $this->assertFalse($event->cancelled); + + $event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true + ]); + + $this->assertSame([], $event->metadata); + $status = $event->status; + $this->assertSame([], $status->metadata); $this->assertSame(Grpc\STATUS_OK, $status->code); $this->assertSame($status_text, $status->details); - // and the server gets FINISHED - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - $status = $event->data; - unset($call); unset($server_call); } public function testClientServerFullRequestResponse() { - $deadline = Grpc\Timeval::inf_future(); + $deadline = Grpc\Timeval::infFuture(); $req_text = 'client_server_full_request_response'; $reply_text = 'reply:client_server_full_request_response'; $status_text = 'status:client_server_full_response_text'; @@ -115,79 +102,52 @@ class EndToEndTest extends PHPUnit_Framework_TestCase{ $call = new Grpc\Call($this->channel, 'dummy_method', $deadline); - $tag = 1; - $call->invoke($this->client_queue, $tag, $tag); - $server_tag = 2; + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => $req_text + ]); - // the client writes - $call->start_write($req_text, $tag); - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type); + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_close); + $this->assertTrue($event->send_message); - // check that a server rpc new was received - $this->server->start(); - $this->server->request_call($server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type); + $event = $this->server->requestCall(); + $this->assertSame('dummy_method', $event->method); $server_call = $event->call; - $this->assertNotNull($server_call); - $server_call->server_accept($this->server_queue, $server_tag); - - $server_call->server_end_initial_metadata(); - - // start the server read - $server_call->start_read($server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\READ, $event->type); - $this->assertSame($req_text, $event->data); - - // the server replies - $server_call->start_write($reply_text, $server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type); - - // the client reads the metadata - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type); - - // the client reads the reply - $call->start_read($tag); - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\READ, $event->type); - $this->assertSame($reply_text, $event->data); - - // the client sends writes done - $call->writes_done($tag); - $event = $this->client_queue->next($deadline); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); - - // the server sends the status - $server_call->start_write_status(GRPC\STATUS_OK, $status_text, $server_tag); - $event = $this->server_queue->next($deadline); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); - - // the client gets FINISHED - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - $status = $event->data; + + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => $reply_text, + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_status); + $this->assertTrue($event->send_message); + $this->assertFalse($event->cancelled); + $this->assertSame($req_text, $event->message); + + $event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, + ]); + + $this->assertSame([], $event->metadata); + $this->assertSame($reply_text, $event->message); + $status = $event->status; + $this->assertSame([], $status->metadata); $this->assertSame(Grpc\STATUS_OK, $status->code); $this->assertSame($status_text, $status->details); - // and the server gets FINISHED - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - unset($call); unset($server_call); } diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php index 896afeac49..0c18cd3e91 100755 --- a/src/php/tests/unit_tests/SecureEndToEndTest.php +++ b/src/php/tests/unit_tests/SecureEndToEndTest.php @@ -33,17 +33,16 @@ */ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{ public function setUp() { - $this->client_queue = new Grpc\CompletionQueue(); - $this->server_queue = new Grpc\CompletionQueue(); $credentials = Grpc\Credentials::createSsl( file_get_contents(dirname(__FILE__) . '/../data/ca.pem')); $server_credentials = Grpc\ServerCredentials::createSsl( null, file_get_contents(dirname(__FILE__) . '/../data/server1.key'), file_get_contents(dirname(__FILE__) . '/../data/server1.pem')); - $this->server = new Grpc\Server($this->server_queue); - $port = $this->server->add_secure_http2_port('0.0.0.0:0', - $server_credentials); + $this->server = new Grpc\Server(); + $port = $this->server->addSecureHttp2Port('0.0.0.0:0', + $server_credentials); + $this->server->start(); $this->channel = new Grpc\Channel( 'localhost:' . $port, [ @@ -55,71 +54,59 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{ public function tearDown() { unset($this->channel); unset($this->server); - unset($this->client_queue); - unset($this->server_queue); } public function testSimpleRequestBody() { - $this->server->start(); - $deadline = Grpc\Timeval::inf_future(); + $deadline = Grpc\Timeval::infFuture(); $status_text = 'xyz'; $call = new Grpc\Call($this->channel, 'dummy_method', $deadline); - $tag = 1; - $call->invoke($this->client_queue, $tag, $tag); - $server_tag = 2; - - $call->writes_done($tag); - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); - - // check that a server rpc new was received - $this->server->request_call($server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type); + + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_close); + + $event = $this->server->requestCall(); + $this->assertSame('dummy_method', $event->method); + $this->assertSame([], $event->metadata); $server_call = $event->call; - $this->assertNotNull($server_call); - $server_call->server_accept($this->server_queue, $server_tag); - - $server_call->server_end_initial_metadata(); - - // the server sends the status - $server_call->start_write_status(Grpc\STATUS_OK, $status_text, $server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); - - // the client gets CLIENT_METADATA_READ - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type); - - // the client gets FINISHED - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - $status = $event->data; + + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text + ], + Grpc\OP_RECV_CLOSE_ON_SERVER => true + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_status); + $this->assertFalse($event->cancelled); + + $event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true + ]); + + $this->assertSame([], $event->metadata); + $status = $event->status; + $this->assertSame([], $status->metadata); $this->assertSame(Grpc\STATUS_OK, $status->code); $this->assertSame($status_text, $status->details); - // and the server gets FINISHED - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - $status = $event->data; - unset($call); unset($server_call); } public function testClientServerFullRequestResponse() { - $this->server->start(); - $deadline = Grpc\Timeval::inf_future(); + $deadline = Grpc\Timeval::infFuture(); $req_text = 'client_server_full_request_response'; $reply_text = 'reply:client_server_full_request_response'; $status_text = 'status:client_server_full_response_text'; @@ -127,78 +114,52 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{ $call = new Grpc\Call($this->channel, 'dummy_method', $deadline); - $tag = 1; - $call->invoke($this->client_queue, $tag, $tag); - - $server_tag = 2; - - // the client writes - $call->start_write($req_text, $tag); - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type); - - // check that a server rpc new was received - $this->server->request_call($server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\SERVER_RPC_NEW, $event->type); + + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_SEND_MESSAGE => $req_text + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_close); + $this->assertTrue($event->send_message); + + $event = $this->server->requestCall(); + $this->assertSame('dummy_method', $event->method); $server_call = $event->call; - $this->assertNotNull($server_call); - $server_call->server_accept($this->server_queue, $server_tag); - - $server_call->server_end_initial_metadata(); - - // start the server read - $server_call->start_read($server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\READ, $event->type); - $this->assertSame($req_text, $event->data); - - // the server replies - $server_call->start_write($reply_text, $server_tag); - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\WRITE_ACCEPTED, $event->type); - - // the client reads the metadata - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\CLIENT_METADATA_READ, $event->type); - - // the client reads the reply - $call->start_read($tag); - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\READ, $event->type); - $this->assertSame($reply_text, $event->data); - - // the client sends writes done - $call->writes_done($tag); - $event = $this->client_queue->next($deadline); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); - - // the server sends the status - $server_call->start_write_status(GRPC\STATUS_OK, $status_text, $server_tag); - $event = $this->server_queue->next($deadline); - $this->assertSame(Grpc\FINISH_ACCEPTED, $event->type); - $this->assertSame(Grpc\OP_OK, $event->data); - - // the client gets FINISHED - $event = $this->client_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - $status = $event->data; + + $event = $server_call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_MESSAGE => $reply_text, + Grpc\OP_SEND_STATUS_FROM_SERVER => [ + 'metadata' => [], + 'code' => Grpc\STATUS_OK, + 'details' => $status_text + ], + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_CLOSE_ON_SERVER => true, + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_status); + $this->assertTrue($event->send_message); + $this->assertFalse($event->cancelled); + $this->assertSame($req_text, $event->message); + + $event = $call->startBatch([ + Grpc\OP_RECV_INITIAL_METADATA => true, + Grpc\OP_RECV_MESSAGE => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, + ]); + + $this->assertSame([], $event->metadata); + $this->assertSame($reply_text, $event->message); + $status = $event->status; + $this->assertSame([], $status->metadata); $this->assertSame(Grpc\STATUS_OK, $status->code); $this->assertSame($status_text, $status->details); - // and the server gets FINISHED - $event = $this->server_queue->next($deadline); - $this->assertNotNull($event); - $this->assertSame(Grpc\FINISHED, $event->type); - unset($call); unset($server_call); } diff --git a/src/php/tests/unit_tests/TimevalTest.php b/src/php/tests/unit_tests/TimevalTest.php index d20069afa1..a8bfcf0ac4 100755 --- a/src/php/tests/unit_tests/TimevalTest.php +++ b/src/php/tests/unit_tests/TimevalTest.php @@ -39,14 +39,14 @@ class TimevalTest extends PHPUnit_Framework_TestCase{ public function testPastIsLessThanZero() { $zero = Grpc\Timeval::zero(); - $past = Grpc\Timeval::inf_past(); + $past = Grpc\Timeval::infPast(); $this->assertLessThan(0, Grpc\Timeval::compare($past, $zero)); $this->assertGreaterThan(0, Grpc\Timeval::compare($zero, $past)); } public function testFutureIsGreaterThanZero() { $zero = Grpc\Timeval::zero(); - $future = Grpc\Timeval::inf_future(); + $future = Grpc\Timeval::infFuture(); $this->assertLessThan(0, Grpc\Timeval::compare($zero, $future)); $this->assertGreaterThan(0, Grpc\Timeval::compare($future, $zero)); } @@ -56,7 +56,7 @@ class TimevalTest extends PHPUnit_Framework_TestCase{ */ public function testNowIsBetweenZeroAndFuture() { $zero = Grpc\Timeval::zero(); - $future = Grpc\Timeval::inf_future(); + $future = Grpc\Timeval::infFuture(); $now = Grpc\Timeval::now(); $this->assertLessThan(0, Grpc\Timeval::compare($zero, $now)); $this->assertLessThan(0, Grpc\Timeval::compare($now, $future)); diff --git a/src/python/README.md b/src/python/README.md index c8057be38b..82bc776732 100644 --- a/src/python/README.md +++ b/src/python/README.md @@ -42,7 +42,14 @@ $ tools/run_tests/run_python.sh Installing ----------------------- -- [Install the gRPC core](https://github.com/grpc/grpc/blob/master/INSTALL) +- Install the gRPC core + - [Debian package](https://github.com/grpc/grpc/releases) + ``` + $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc_0.5.0_amd64.deb + $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc-dev_0.5.0_amd64.deb + $ sudo dpkg -i libgrpc_0.5.0_amd64.deb libgrpc-dev_0.5.0_amd64.deb + ``` + - [From source](https://github.com/grpc/grpc/blob/master/INSTALL) - Install gRPC Python's dependencies ``` @@ -53,3 +60,16 @@ $ pip install -r src/python/requirements.txt ``` $ pip install src/python/src ``` + +Packaging to PyPI +----------------------- + +- Install packaging dependencies +``` +$ pip install setuptools twine +``` + +- Push to PyPI +``` +$ ../../tools/distrib/python/submit.py +``` diff --git a/src/python/interop/interop/_insecure_interop_test.py b/src/python/interop/interop/_insecure_interop_test.py index e4ddff1a0b..42e7a4d5c4 100644 --- a/src/python/interop/interop/_insecure_interop_test.py +++ b/src/python/interop/interop/_insecure_interop_test.py @@ -42,11 +42,11 @@ class InsecureInteropTest( unittest.TestCase): def setUp(self): - self.server = implementations.insecure_server( + self.server = implementations.server( methods.SERVICE_NAME, methods.SERVER_METHODS, 0) self.server.start() port = self.server.port() - self.stub = implementations.insecure_stub( + self.stub = implementations.stub( methods.SERVICE_NAME, methods.CLIENT_METHODS, 'localhost', port) def tearDown(self): diff --git a/src/python/interop/interop/_interop_test_case.py b/src/python/interop/interop/_interop_test_case.py index fec8f1915d..cd6a574e90 100644 --- a/src/python/interop/interop/_interop_test_case.py +++ b/src/python/interop/interop/_interop_test_case.py @@ -40,16 +40,16 @@ class InteropTestCase(object): """ def testEmptyUnary(self): - methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub) + methods.TestCase.EMPTY_UNARY.test_interoperability(self.stub, None) def testLargeUnary(self): - methods.TestCase.LARGE_UNARY.test_interoperability(self.stub) + methods.TestCase.LARGE_UNARY.test_interoperability(self.stub, None) def testServerStreaming(self): - methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub) + methods.TestCase.SERVER_STREAMING.test_interoperability(self.stub, None) def testClientStreaming(self): - methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub) + methods.TestCase.CLIENT_STREAMING.test_interoperability(self.stub, None) def testPingPong(self): - methods.TestCase.PING_PONG.test_interoperability(self.stub) + methods.TestCase.PING_PONG.test_interoperability(self.stub, None) diff --git a/src/python/interop/interop/_secure_interop_test.py b/src/python/interop/interop/_secure_interop_test.py index 214212dca4..27e76315b6 100644 --- a/src/python/interop/interop/_secure_interop_test.py +++ b/src/python/interop/interop/_secure_interop_test.py @@ -45,14 +45,15 @@ class SecureInteropTest( unittest.TestCase): def setUp(self): - self.server = implementations.secure_server( + self.server = implementations.server( methods.SERVICE_NAME, methods.SERVER_METHODS, 0, - resources.private_key(), resources.certificate_chain()) + private_key=resources.private_key(), + certificate_chain=resources.certificate_chain()) self.server.start() port = self.server.port() - self.stub = implementations.secure_stub( + self.stub = implementations.stub( methods.SERVICE_NAME, methods.CLIENT_METHODS, 'localhost', port, - resources.test_root_certificates(), None, None, + secure=True, root_certificates=resources.test_root_certificates(), server_host_override=_SERVER_HOST_OVERRIDE) def tearDown(self): diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py index fb7dfb5729..bae5e17460 100644 --- a/src/python/interop/interop/client.py +++ b/src/python/interop/interop/client.py @@ -30,6 +30,7 @@ """The Python implementation of the GRPC interoperability test client.""" import argparse +from oauth2client import client as oauth2client_client from grpc.early_adopter import implementations @@ -44,9 +45,6 @@ def _args(): parser.add_argument( '--server_host', help='the host to which to connect', type=str) parser.add_argument( - '--server_host_override', - help='the server host to which to claim to connect', type=str) - parser.add_argument( '--server_port', help='the port to which to connect', type=int) parser.add_argument( '--test_case', help='the test case to execute', type=str) @@ -56,24 +54,40 @@ def _args(): parser.add_argument( '--use_test_ca', help='replace platform root CAs with ca.pem', action='store_true') + parser.add_argument( + '--server_host_override', + help='the server host to which to claim to connect', type=str) + parser.add_argument('--oauth_scope', help='scope for OAuth tokens', type=str) + parser.add_argument( + '--default_service_account', + help='email address of the default service account', type=str) return parser.parse_args() +def _oauth_access_token(args): + credentials = client.GoogleCredentials.get_application_default() + scoped_credentials = credentials.create_scoped([args.oauth_scope]) + return scoped_credentials.get_access_token().access_token def _stub(args): + if args.oauth_scope: + metadata_transformer = lambda x: [('Authorization', 'Bearer %s' % _oauth_access_token(args))] + else: + metadata_transformer = lambda x: [] if args.use_tls: if args.use_test_ca: root_certificates = resources.test_root_certificates() else: root_certificates = resources.prod_root_certificates() - stub = implementations.secure_stub( + stub = implementations.stub( methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host, - args.server_port, root_certificates, None, None, + args.server_port, metadata_transformer=metadata_transformer, + secure=True, root_certificates=root_certificates, server_host_override=args.server_host_override) else: - stub = implementations.insecure_stub( + stub = implementations.stub( methods.SERVICE_NAME, methods.CLIENT_METHODS, args.server_host, - args.server_port) + args.server_port, secure=False) return stub @@ -89,7 +103,7 @@ def _test_interoperability(): args = _args() stub = _stub(args) test_case = _test_case_from_arg(args.test_case) - test_case.test_interoperability(stub) + test_case.test_interoperability(stub, args) if __name__ == '__main__': diff --git a/src/python/interop/interop/empty_pb2.py b/src/python/interop/interop/empty_pb2.py index 732a358a36..8c1ce2f13e 100644 --- a/src/python/interop/interop/empty_pb2.py +++ b/src/python/interop/interop/empty_pb2.py @@ -57,6 +57,7 @@ Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), d _sym_db.RegisterMessage(Empty) -from grpc.framework.face import demonstration as _face_testing -from grpc.framework.face import interfaces as _face_interfaces +import abc +from grpc.early_adopter import implementations +from grpc.framework.alpha import utilities # @@protoc_insertion_point(module_scope) diff --git a/src/python/interop/interop/messages_pb2.py b/src/python/interop/interop/messages_pb2.py index d449a99140..0bf3d86a31 100644 --- a/src/python/interop/interop/messages_pb2.py +++ b/src/python/interop/interop/messages_pb2.py @@ -441,6 +441,7 @@ StreamingOutputCallResponse = _reflection.GeneratedProtocolMessageType('Streamin _sym_db.RegisterMessage(StreamingOutputCallResponse) -from grpc.framework.face import demonstration as _face_testing -from grpc.framework.face import interfaces as _face_interfaces +import abc +from grpc.early_adopter import implementations +from grpc.framework.alpha import utilities # @@protoc_insertion_point(module_scope) diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py index 79550a3789..c69771dff1 100644 --- a/src/python/interop/interop/methods.py +++ b/src/python/interop/interop/methods.py @@ -30,8 +30,12 @@ """Implementations of interoperability test methods.""" import enum +import json +import os import threading +from oauth2client import client as oauth2client_client + from grpc.framework.alpha import utilities from interop import empty_pb2 @@ -150,19 +154,12 @@ SERVER_METHODS = { } -def _empty_unary(stub): - with stub: - response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) - if not isinstance(response, empty_pb2.Empty): - raise TypeError( - 'response is of type "%s", not empty_pb2.Empty!', type(response)) - - -def _large_unary(stub): +def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope): with stub: request = messages_pb2.SimpleRequest( response_type=messages_pb2.COMPRESSABLE, response_size=314159, - payload=messages_pb2.Payload(body=b'\x00' * 271828)) + payload=messages_pb2.Payload(body=b'\x00' * 271828), + fill_username=fill_username, fill_oauth_scope=fill_oauth_scope) response_future = stub.UnaryCall.async(request, _TIMEOUT) response = response_future.result() if response.payload.type is not messages_pb2.COMPRESSABLE: @@ -171,6 +168,19 @@ def _large_unary(stub): if len(response.payload.body) != 314159: raise ValueError( 'response body of incorrect size %d!' % len(response.payload.body)) + return response + + +def _empty_unary(stub): + with stub: + response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) + if not isinstance(response, empty_pb2.Empty): + raise TypeError( + 'response is of type "%s", not empty_pb2.Empty!', type(response)) + + +def _large_unary(stub): + _large_unary_common_behavior(stub, False, False) def _client_streaming(stub): @@ -266,6 +276,28 @@ def _ping_pong(stub): pipe.close() +def _compute_engine_creds(stub, args): + response = _large_unary_common_behavior(stub, True, True) + if args.default_service_account != response.username: + raise ValueError( + 'expected username %s, got %s' % (args.default_service_account, + response.username)) + + +def _service_account_creds(stub, args): + json_key_filename = os.environ[ + oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] + wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] + response = _large_unary_common_behavior(stub, True, True) + if wanted_email != response.username: + raise ValueError( + 'expected username %s, got %s' % (wanted_email, response.username)) + if response.oauth_scope in args.oauth_scope: + raise ValueError( + 'expected to find oauth scope "%s" in received "%s"' % + (response.oauth_scope, args.oauth_scope)) + + @enum.unique class TestCase(enum.Enum): EMPTY_UNARY = 'empty_unary' @@ -273,8 +305,10 @@ class TestCase(enum.Enum): SERVER_STREAMING = 'server_streaming' CLIENT_STREAMING = 'client_streaming' PING_PONG = 'ping_pong' + COMPUTE_ENGINE_CREDS = 'compute_engine_creds' + SERVICE_ACCOUNT_CREDS = 'service_account_creds' - def test_interoperability(self, stub): + def test_interoperability(self, stub, args): if self is TestCase.EMPTY_UNARY: _empty_unary(stub) elif self is TestCase.LARGE_UNARY: @@ -285,5 +319,9 @@ class TestCase(enum.Enum): _client_streaming(stub) elif self is TestCase.PING_PONG: _ping_pong(stub) + elif self is TestCase.COMPUTE_ENGINE_CREDS: + _compute_engine_creds(stub, args) + elif self is TestCase.SERVICE_ACCOUNT_CREDS: + _service_account_creds(stub, args) else: raise NotImplementedError('Test case "%s" not implemented!' % self.name) diff --git a/src/python/interop/interop/server.py b/src/python/interop/interop/server.py index 5791203743..a67d412038 100644 --- a/src/python/interop/interop/server.py +++ b/src/python/interop/interop/server.py @@ -53,11 +53,11 @@ def serve(): if args.use_tls: private_key = resources.private_key() certificate_chain = resources.certificate_chain() - server = implementations.secure_server( - methods.SERVICE_NAME, methods.SERVER_METHODS, args.port, private_key, - certificate_chain) + server = implementations.server( + methods.SERVICE_NAME, methods.SERVER_METHODS, args.port, + private_key=private_key, certificate_chain=certificate_chain) else: - server = implementations.insecure_server( + server = implementations.server( methods.SERVICE_NAME, methods.SERVER_METHODS, args.port) server.start() diff --git a/src/python/interop/interop/test_pb2.py b/src/python/interop/interop/test_pb2.py index e86094611b..71325d5a9f 100644 --- a/src/python/interop/interop/test_pb2.py +++ b/src/python/interop/interop/test_pb2.py @@ -29,121 +29,150 @@ _sym_db.RegisterFileDescriptor(DESCRIPTOR) -from grpc.framework.face import demonstration as _face_testing -from grpc.framework.face import interfaces as _face_interfaces -class TestServiceService(object): +import abc +from grpc.early_adopter import implementations +from grpc.framework.alpha import utilities +class EarlyAdopterTestServiceServicer(object): """<fill me in later!>""" - def __init__(self): - pass -class TestServiceServicer(object): - """<fill me in later!>""" - def EmptyCall(self, arg): + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def EmptyCall(self, request, context): + raise NotImplementedError() + @abc.abstractmethod + def UnaryCall(self, request, context): raise NotImplementedError() - def UnaryCall(self, arg): + @abc.abstractmethod + def StreamingOutputCall(self, request, context): raise NotImplementedError() - def StreamingOutputCall(self, arg): + @abc.abstractmethod + def StreamingInputCall(self, request_iterator, context): raise NotImplementedError() - def StreamingInputCall(self, arg): + @abc.abstractmethod + def FullDuplexCall(self, request_iterator, context): raise NotImplementedError() - def FullDuplexCall(self, arg): + @abc.abstractmethod + def HalfDuplexCall(self, request_iterator, context): + raise NotImplementedError() +class EarlyAdopterTestServiceServer(object): + """<fill me in later!>""" + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def start(self): raise NotImplementedError() - def HalfDuplexCall(self, arg): + @abc.abstractmethod + def stop(self): raise NotImplementedError() -class TestServiceStub(object): +class EarlyAdopterTestServiceStub(object): """<fill me in later!>""" - def EmptyCall(self, arg): + __metaclass__ = abc.ABCMeta + @abc.abstractmethod + def EmptyCall(self, request): raise NotImplementedError() EmptyCall.async = None - def UnaryCall(self, arg): + @abc.abstractmethod + def UnaryCall(self, request): raise NotImplementedError() UnaryCall.async = None - def StreamingOutputCall(self, arg): + @abc.abstractmethod + def StreamingOutputCall(self, request): raise NotImplementedError() StreamingOutputCall.async = None - def StreamingInputCall(self, arg): + @abc.abstractmethod + def StreamingInputCall(self, request_iterator): raise NotImplementedError() StreamingInputCall.async = None - def FullDuplexCall(self, arg): + @abc.abstractmethod + def FullDuplexCall(self, request_iterator): raise NotImplementedError() FullDuplexCall.async = None - def HalfDuplexCall(self, arg): + @abc.abstractmethod + def HalfDuplexCall(self, request_iterator): raise NotImplementedError() HalfDuplexCall.async = None -class _TestServiceStub(TestServiceStub): - def __init__(self, face_stub, default_timeout): - self._face_stub = face_stub - self._default_timeout = default_timeout - stub_self = self - class EmptyCall(object): - def __call__(self, arg): - return stub_self._face_stub.blocking_value_in_value_out("EmptyCall", arg, stub_self._default_timeout) - def async(self, arg): - return stub_self._face_stub.future_value_in_value_out("EmptyCall", arg, stub_self._default_timeout) - self.EmptyCall = EmptyCall() - class UnaryCall(object): - def __call__(self, arg): - return stub_self._face_stub.blocking_value_in_value_out("UnaryCall", arg, stub_self._default_timeout) - def async(self, arg): - return stub_self._face_stub.future_value_in_value_out("UnaryCall", arg, stub_self._default_timeout) - self.UnaryCall = UnaryCall() - class StreamingOutputCall(object): - def __call__(self, arg): - return stub_self._face_stub.inline_value_in_stream_out("StreamingOutputCall", arg, stub_self._default_timeout) - def async(self, arg): - return stub_self._face_stub.inline_value_in_stream_out("StreamingOutputCall", arg, stub_self._default_timeout) - self.StreamingOutputCall = StreamingOutputCall() - class StreamingInputCall(object): - def __call__(self, arg): - return stub_self._face_stub.blocking_stream_in_value_out("StreamingInputCall", arg, stub_self._default_timeout) - def async(self, arg): - return stub_self._face_stub.future_stream_in_value_out("StreamingInputCall", arg, stub_self._default_timeout) - self.StreamingInputCall = StreamingInputCall() - class FullDuplexCall(object): - def __call__(self, arg): - return stub_self._face_stub.inline_stream_in_stream_out("FullDuplexCall", arg, stub_self._default_timeout) - def async(self, arg): - return stub_self._face_stub.inline_stream_in_stream_out("FullDuplexCall", arg, stub_self._default_timeout) - self.FullDuplexCall = FullDuplexCall() - class HalfDuplexCall(object): - def __call__(self, arg): - return stub_self._face_stub.inline_stream_in_stream_out("HalfDuplexCall", arg, stub_self._default_timeout) - def async(self, arg): - return stub_self._face_stub.inline_stream_in_stream_out("HalfDuplexCall", arg, stub_self._default_timeout) - self.HalfDuplexCall = HalfDuplexCall() -def mock_TestService(servicer, default_timeout): - value_in_value_out = {} - value_in_stream_out = {} - stream_in_value_out = {} - stream_in_stream_out = {} - class EmptyCall(_face_interfaces.InlineValueInValueOutMethod): - def service(self, request, context): - return servicer.EmptyCall(request) - value_in_value_out['EmptyCall'] = EmptyCall() - class UnaryCall(_face_interfaces.InlineValueInValueOutMethod): - def service(self, request, context): - return servicer.UnaryCall(request) - value_in_value_out['UnaryCall'] = UnaryCall() - class StreamingOutputCall(_face_interfaces.InlineValueInStreamOutMethod): - def service(self, request, context): - return servicer.StreamingOutputCall(request) - value_in_stream_out['StreamingOutputCall'] = StreamingOutputCall() - class StreamingInputCall(_face_interfaces.InlineStreamInValueOutMethod): - def service(self, request, context): - return servicer.StreamingInputCall(request) - stream_in_value_out['StreamingInputCall'] = StreamingInputCall() - class FullDuplexCall(_face_interfaces.InlineStreamInStreamOutMethod): - def service(self, request, context): - return servicer.FullDuplexCall(request) - stream_in_stream_out['FullDuplexCall'] = FullDuplexCall() - class HalfDuplexCall(_face_interfaces.InlineStreamInStreamOutMethod): - def service(self, request, context): - return servicer.HalfDuplexCall(request) - stream_in_stream_out['HalfDuplexCall'] = HalfDuplexCall() - face_linked_pair = _face_testing.server_and_stub(default_timeout,inline_value_in_value_out_methods=value_in_value_out,inline_value_in_stream_out_methods=value_in_stream_out,inline_stream_in_value_out_methods=stream_in_value_out,inline_stream_in_stream_out_methods=stream_in_stream_out) - class LinkedPair(object): - def __init__(self, server, stub): - self.server = server - self.stub = stub - stub = _TestServiceStub(face_linked_pair.stub, default_timeout) - return LinkedPair(None, stub) +def early_adopter_create_TestService_server(servicer, port, private_key=None, certificate_chain=None): + import test.cpp.interop.empty_pb2 + import test.cpp.interop.empty_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + method_service_descriptions = { + "EmptyCall": utilities.unary_unary_service_description( + servicer.EmptyCall, + test.cpp.interop.empty_pb2.Empty.FromString, + test.cpp.interop.empty_pb2.Empty.SerializeToString, + ), + "FullDuplexCall": utilities.stream_stream_service_description( + servicer.FullDuplexCall, + test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString, + test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString, + ), + "HalfDuplexCall": utilities.stream_stream_service_description( + servicer.HalfDuplexCall, + test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString, + test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString, + ), + "StreamingInputCall": utilities.stream_unary_service_description( + servicer.StreamingInputCall, + test.cpp.interop.messages_pb2.StreamingInputCallRequest.FromString, + test.cpp.interop.messages_pb2.StreamingInputCallResponse.SerializeToString, + ), + "StreamingOutputCall": utilities.unary_stream_service_description( + servicer.StreamingOutputCall, + test.cpp.interop.messages_pb2.StreamingOutputCallRequest.FromString, + test.cpp.interop.messages_pb2.StreamingOutputCallResponse.SerializeToString, + ), + "UnaryCall": utilities.unary_unary_service_description( + servicer.UnaryCall, + test.cpp.interop.messages_pb2.SimpleRequest.FromString, + test.cpp.interop.messages_pb2.SimpleResponse.SerializeToString, + ), + } + return implementations.server("grpc.testing.TestService", method_service_descriptions, port, private_key=private_key, certificate_chain=certificate_chain) +def early_adopter_create_TestService_stub(host, port, metadata_transformer=None, secure=False, root_certificates=None, private_key=None, certificate_chain=None, server_host_override=None): + import test.cpp.interop.empty_pb2 + import test.cpp.interop.empty_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + import test.cpp.interop.messages_pb2 + method_invocation_descriptions = { + "EmptyCall": utilities.unary_unary_invocation_description( + test.cpp.interop.empty_pb2.Empty.SerializeToString, + test.cpp.interop.empty_pb2.Empty.FromString, + ), + "FullDuplexCall": utilities.stream_stream_invocation_description( + test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString, + test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString, + ), + "HalfDuplexCall": utilities.stream_stream_invocation_description( + test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString, + test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString, + ), + "StreamingInputCall": utilities.stream_unary_invocation_description( + test.cpp.interop.messages_pb2.StreamingInputCallRequest.SerializeToString, + test.cpp.interop.messages_pb2.StreamingInputCallResponse.FromString, + ), + "StreamingOutputCall": utilities.unary_stream_invocation_description( + test.cpp.interop.messages_pb2.StreamingOutputCallRequest.SerializeToString, + test.cpp.interop.messages_pb2.StreamingOutputCallResponse.FromString, + ), + "UnaryCall": utilities.unary_unary_invocation_description( + test.cpp.interop.messages_pb2.SimpleRequest.SerializeToString, + test.cpp.interop.messages_pb2.SimpleResponse.FromString, + ), + } + return implementations.stub("grpc.testing.TestService", method_invocation_descriptions, host, port, metadata_transformer=metadata_transformer, secure=secure, root_certificates=root_certificates, private_key=private_key, certificate_chain=certificate_chain, server_host_override=server_host_override) # @@protoc_insertion_point(module_scope) diff --git a/src/python/interop/setup.py b/src/python/interop/setup.py index 6db5435090..502fcbedd8 100644 --- a/src/python/interop/setup.py +++ b/src/python/interop/setup.py @@ -29,7 +29,7 @@ """A setup module for the GRPC Python interop testing package.""" -from distutils import core as _core +import setuptools _PACKAGES = ( 'interop', @@ -45,9 +45,13 @@ _PACKAGE_DATA = { 'credentials/server1.pem',] } -_INSTALL_REQUIRES = ['grpc-2015>=0.0.1'] +_INSTALL_REQUIRES = ['oauth2client>=1.4.7', 'grpcio>=0.4.0a4'] -_core.setup( - name='interop', version='0.0.1', packages=_PACKAGES, - package_dir=_PACKAGE_DIRECTORIES, package_data=_PACKAGE_DATA, - install_requires=_INSTALL_REQUIRES) +setuptools.setup( + name='interop', + version='0.0.1', + packages=_PACKAGES, + package_dir=_PACKAGE_DIRECTORIES, + package_data=_PACKAGE_DATA, + install_requires=_INSTALL_REQUIRES +) diff --git a/src/python/src/.gitignore b/src/python/src/.gitignore new file mode 100644 index 0000000000..bc15a52cf1 --- /dev/null +++ b/src/python/src/.gitignore @@ -0,0 +1,3 @@ +MANIFEST +grpcio.egg-info/ +dist/ diff --git a/src/python/src/MANIFEST.in b/src/python/src/MANIFEST.in new file mode 100644 index 0000000000..6f32db0548 --- /dev/null +++ b/src/python/src/MANIFEST.in @@ -0,0 +1 @@ +graft grpc diff --git a/src/python/src/README.rst b/src/python/src/README.rst new file mode 100644 index 0000000000..bc1815febc --- /dev/null +++ b/src/python/src/README.rst @@ -0,0 +1,27 @@ +gRPC Python +=========== + +Package for GRPC Python. + +Dependencies +------------ + +Ensure that you have installed GRPC core. + +On debian linux systems, install from our released deb package: + +:: + + $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc_0.5.0_amd64.deb + $ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc-dev_0.5.0_amd64.deb + $ sudo dpkg -i libgrpc_0.5.0_amd64.deb libgrpc-dev_0.5.0_amd64.deb + +Otherwise, install from source: + +:: + + git clone https://github.com/grpc/grpc.git + cd grpc + ./configure + make && make install + diff --git a/src/python/src/grpc/_adapter/_call.c b/src/python/src/grpc/_adapter/_call.c index d8806e5680..bf96c1a3fa 100644 --- a/src/python/src/grpc/_adapter/_call.c +++ b/src/python/src/grpc/_adapter/_call.c @@ -160,8 +160,22 @@ static const PyObject *pygrpc_call_accept(Call *self, PyObject *args) { return result; } +static const PyObject *pygrpc_call_add_metadata(Call *self, PyObject *args) { + const char* key = NULL; + const char* value = NULL; + int value_length = 0; + grpc_metadata metadata; + if (!PyArg_ParseTuple(args, "ss#", &key, &value, &value_length)) { + return NULL; + } + metadata.key = key; + metadata.value = value; + metadata.value_length = value_length; + return pygrpc_translate_call_error( + grpc_call_add_metadata_old(self->c_call, &metadata, 0)); +} + static const PyObject *pygrpc_call_premetadata(Call *self) { - /* TODO(nathaniel): Metadata support. */ return pygrpc_translate_call_error( grpc_call_server_end_initial_metadata_old(self->c_call, 0)); } @@ -236,6 +250,11 @@ static PyMethodDef methods[] = { {"complete", (PyCFunction)pygrpc_call_complete, METH_O, "Complete writes to this call."}, {"accept", (PyCFunction)pygrpc_call_accept, METH_VARARGS, "Accept an RPC."}, + {"add_metadata", (PyCFunction)pygrpc_call_add_metadata, METH_VARARGS, + "Add metadata to the call. May not be called after invoke on the client " + "side. On the server side: when called before premetadata it provides " + "'leading' metadata, when called after premetadata but before status it " + "provides 'trailing metadata'; may not be called after status."}, {"premetadata", (PyCFunction)pygrpc_call_premetadata, METH_VARARGS, "Indicate the end of leading metadata in the response."}, {"read", (PyCFunction)pygrpc_call_read, METH_O, diff --git a/src/python/src/grpc/_adapter/_call.h b/src/python/src/grpc/_adapter/_call.h index a936e23023..c04a2285f7 100644 --- a/src/python/src/grpc/_adapter/_call.h +++ b/src/python/src/grpc/_adapter/_call.h @@ -37,7 +37,10 @@ #include <Python.h> #include <grpc/grpc.h> -typedef struct { PyObject_HEAD grpc_call *c_call; } Call; +typedef struct { + PyObject_HEAD + grpc_call *c_call; +} Call; PyTypeObject pygrpc_CallType; diff --git a/src/python/src/grpc/_adapter/_channel.h b/src/python/src/grpc/_adapter/_channel.h index 6241ccd02e..afc0f80359 100644 --- a/src/python/src/grpc/_adapter/_channel.h +++ b/src/python/src/grpc/_adapter/_channel.h @@ -37,7 +37,10 @@ #include <Python.h> #include <grpc/grpc.h> -typedef struct { PyObject_HEAD grpc_channel *c_channel; } Channel; +typedef struct { + PyObject_HEAD + grpc_channel *c_channel; +} Channel; PyTypeObject pygrpc_ChannelType; diff --git a/src/python/src/grpc/_adapter/_client_credentials.h b/src/python/src/grpc/_adapter/_client_credentials.h index 664dc80d75..bb9f7f0c3a 100644 --- a/src/python/src/grpc/_adapter/_client_credentials.h +++ b/src/python/src/grpc/_adapter/_client_credentials.h @@ -38,7 +38,8 @@ #include <grpc/grpc_security.h> typedef struct { - PyObject_HEAD grpc_credentials *c_client_credentials; + PyObject_HEAD + grpc_credentials *c_client_credentials; } ClientCredentials; PyTypeObject pygrpc_ClientCredentialsType; diff --git a/src/python/src/grpc/_adapter/_completion_queue.c b/src/python/src/grpc/_adapter/_completion_queue.c index b56ca1926e..a639eff53e 100644 --- a/src/python/src/grpc/_adapter/_completion_queue.c +++ b/src/python/src/grpc/_adapter/_completion_queue.c @@ -115,35 +115,56 @@ static PyObject *pygrpc_status_code(grpc_status_code c_status_code) { } } +static PyObject *pygrpc_metadata_collection_get( + grpc_metadata *metadata_elements, size_t count) { + PyObject *metadata = PyList_New(count); + size_t i; + for (i = 0; i < count; ++i) { + grpc_metadata elem = metadata_elements[i]; + PyObject *key = PyString_FromString(elem.key); + PyObject *value = PyString_FromStringAndSize(elem.value, elem.value_length); + PyObject* kvp = PyTuple_Pack(2, key, value); + /* n.b. PyList_SetItem *steals* a reference to the set element. */ + PyList_SetItem(metadata, i, kvp); + Py_DECREF(key); + Py_DECREF(value); + } + return metadata; +} + static PyObject *pygrpc_stop_event_args(grpc_event *c_event) { - return PyTuple_Pack(7, stop_event_kind, Py_None, Py_None, Py_None, - Py_None, Py_None, Py_None); + return PyTuple_Pack(8, stop_event_kind, Py_None, Py_None, Py_None, + Py_None, Py_None, Py_None, Py_None); } static PyObject *pygrpc_write_event_args(grpc_event *c_event) { PyObject *write_accepted = c_event->data.write_accepted == GRPC_OP_OK ? Py_True : Py_False; - return PyTuple_Pack(7, write_event_kind, (PyObject *)c_event->tag, - write_accepted, Py_None, Py_None, Py_None, Py_None); + return PyTuple_Pack(8, write_event_kind, (PyObject *)c_event->tag, + write_accepted, Py_None, Py_None, Py_None, Py_None, + Py_None); } static PyObject *pygrpc_complete_event_args(grpc_event *c_event) { PyObject *complete_accepted = c_event->data.finish_accepted == GRPC_OP_OK ? Py_True : Py_False; - return PyTuple_Pack(7, complete_event_kind, (PyObject *)c_event->tag, - Py_None, complete_accepted, Py_None, Py_None, Py_None); + return PyTuple_Pack(8, complete_event_kind, (PyObject *)c_event->tag, + Py_None, complete_accepted, Py_None, Py_None, Py_None, + Py_None); } static PyObject *pygrpc_service_event_args(grpc_event *c_event) { if (c_event->data.server_rpc_new.method == NULL) { - return PyTuple_Pack(7, service_event_kind, c_event->tag, - Py_None, Py_None, Py_None, Py_None, Py_None); + return PyTuple_Pack( + 8, service_event_kind, c_event->tag, Py_None, Py_None, Py_None, Py_None, + Py_None, Py_None); } else { PyObject *method = NULL; PyObject *host = NULL; PyObject *service_deadline = NULL; Call *call = NULL; PyObject *service_acceptance = NULL; + PyObject *metadata = NULL; PyObject *event_args = NULL; method = PyBytes_FromString(c_event->data.server_rpc_new.method); @@ -173,11 +194,16 @@ static PyObject *pygrpc_service_event_args(grpc_event *c_event) { goto error; } - event_args = PyTuple_Pack(7, service_event_kind, + metadata = pygrpc_metadata_collection_get( + c_event->data.server_rpc_new.metadata_elements, + c_event->data.server_rpc_new.metadata_count); + event_args = PyTuple_Pack(8, service_event_kind, (PyObject *)c_event->tag, Py_None, Py_None, - service_acceptance, Py_None, Py_None); + service_acceptance, Py_None, Py_None, + metadata); Py_DECREF(service_acceptance); + Py_DECREF(metadata); error: Py_XDECREF(call); Py_XDECREF(method); @@ -190,8 +216,8 @@ error: static PyObject *pygrpc_read_event_args(grpc_event *c_event) { if (c_event->data.read == NULL) { - return PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag, - Py_None, Py_None, Py_None, Py_None, Py_None); + return PyTuple_Pack(8, read_event_kind, (PyObject *)c_event->tag, + Py_None, Py_None, Py_None, Py_None, Py_None, Py_None); } else { size_t length; size_t offset; @@ -216,17 +242,23 @@ static PyObject *pygrpc_read_event_args(grpc_event *c_event) { if (bytes == NULL) { return NULL; } - event_args = PyTuple_Pack(7, read_event_kind, (PyObject *)c_event->tag, - Py_None, Py_None, Py_None, bytes, Py_None); + event_args = PyTuple_Pack(8, read_event_kind, (PyObject *)c_event->tag, + Py_None, Py_None, Py_None, bytes, Py_None, + Py_None); Py_DECREF(bytes); return event_args; } } static PyObject *pygrpc_metadata_event_args(grpc_event *c_event) { - /* TODO(nathaniel): Actual transmission of metadata. */ - return PyTuple_Pack(7, metadata_event_kind, (PyObject *)c_event->tag, - Py_None, Py_None, Py_None, Py_None, Py_None); + PyObject *metadata = pygrpc_metadata_collection_get( + c_event->data.client_metadata_read.elements, + c_event->data.client_metadata_read.count); + PyObject* result = PyTuple_Pack( + 8, metadata_event_kind, (PyObject *)c_event->tag, Py_None, Py_None, + Py_None, Py_None, Py_None, metadata); + Py_DECREF(metadata); + return result; } static PyObject *pygrpc_finished_event_args(grpc_event *c_event) { @@ -234,6 +266,7 @@ static PyObject *pygrpc_finished_event_args(grpc_event *c_event) { PyObject *details; PyObject *status; PyObject *event_args; + PyObject *metadata; code = pygrpc_status_code(c_event->data.finished.status); if (code == NULL) { @@ -253,9 +286,14 @@ static PyObject *pygrpc_finished_event_args(grpc_event *c_event) { if (status == NULL) { return NULL; } - event_args = PyTuple_Pack(7, finish_event_kind, (PyObject *)c_event->tag, - Py_None, Py_None, Py_None, Py_None, status); + metadata = pygrpc_metadata_collection_get( + c_event->data.finished.metadata_elements, + c_event->data.finished.metadata_count); + event_args = PyTuple_Pack(8, finish_event_kind, (PyObject *)c_event->tag, + Py_None, Py_None, Py_None, Py_None, status, + metadata); Py_DECREF(status); + Py_DECREF(metadata); return event_args; } diff --git a/src/python/src/grpc/_adapter/_completion_queue.h b/src/python/src/grpc/_adapter/_completion_queue.h index 8e5ee9f406..9b377d15d9 100644 --- a/src/python/src/grpc/_adapter/_completion_queue.h +++ b/src/python/src/grpc/_adapter/_completion_queue.h @@ -38,7 +38,8 @@ #include <grpc/grpc.h> typedef struct { - PyObject_HEAD grpc_completion_queue *c_completion_queue; + PyObject_HEAD + grpc_completion_queue *c_completion_queue; } CompletionQueue; PyTypeObject pygrpc_CompletionQueueType; diff --git a/src/python/src/grpc/_adapter/_datatypes.py b/src/python/src/grpc/_adapter/_datatypes.py index e271ec83b9..3b22784243 100644 --- a/src/python/src/grpc/_adapter/_datatypes.py +++ b/src/python/src/grpc/_adapter/_datatypes.py @@ -70,7 +70,7 @@ class Event( collections.namedtuple( 'Event', ['kind', 'tag', 'write_accepted', 'complete_accepted', - 'service_acceptance', 'bytes', 'status'])): + 'service_acceptance', 'bytes', 'status', 'metadata'])): """Describes an event emitted from a completion queue.""" @enum.unique diff --git a/src/python/src/grpc/_adapter/_links_test.py b/src/python/src/grpc/_adapter/_links_test.py index cfdcc2c4bc..4987be389a 100644 --- a/src/python/src/grpc/_adapter/_links_test.py +++ b/src/python/src/grpc/_adapter/_links_test.py @@ -43,6 +43,14 @@ _IDENTITY = lambda x: x _TIMEOUT = 2 +# TODO(nathaniel): End-to-end metadata testing. +def _transform_metadata(unused_metadata): + return ( + ('one unused key', 'one unused value'), + ('another unused key', 'another unused value'), +) + + class RoundTripTest(unittest.TestCase): def setUp(self): @@ -76,7 +84,8 @@ class RoundTripTest(unittest.TestCase): rear_link = rear.RearLink( 'localhost', port, self.rear_link_pool, {test_method: None}, - {test_method: None}, False, None, None, None) + {test_method: None}, False, None, None, None, + metadata_transformer=_transform_metadata) rear_link.join_fore_link(test_fore_link) test_fore_link.join_rear_link(rear_link) rear_link.start() diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py index b04ac1c950..e88b70969c 100644 --- a/src/python/src/grpc/_adapter/_low_test.py +++ b/src/python/src/grpc/_adapter/_low_test.py @@ -115,6 +115,18 @@ class EchoTest(unittest.TestCase): def _perform_echo_test(self, test_data): method = 'test method' details = 'test details' + server_leading_metadata_key = 'my_server_leading_key' + server_leading_metadata_value = 'my_server_leading_value' + server_trailing_metadata_key = 'my_server_trailing_key' + server_trailing_metadata_value = 'my_server_trailing_value' + client_metadata_key = 'my_client_key' + client_metadata_value = 'my_client_value' + server_leading_binary_metadata_key = 'my_server_leading_key-bin' + server_leading_binary_metadata_value = b'\0'*2047 + server_trailing_binary_metadata_key = 'my_server_trailing_key-bin' + server_trailing_binary_metadata_value = b'\0'*2047 + client_binary_metadata_key = 'my_client_key-bin' + client_binary_metadata_value = b'\0'*2047 deadline = _FUTURE metadata_tag = object() finish_tag = object() @@ -128,6 +140,9 @@ class EchoTest(unittest.TestCase): client_data = [] client_call = _low.Call(self.channel, method, self.host, deadline) + client_call.add_metadata(client_metadata_key, client_metadata_value) + client_call.add_metadata(client_binary_metadata_key, + client_binary_metadata_value) client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag) @@ -139,15 +154,31 @@ class EchoTest(unittest.TestCase): self.assertEqual(method, service_accepted.service_acceptance.method) self.assertEqual(self.host, service_accepted.service_acceptance.host) self.assertIsNotNone(service_accepted.service_acceptance.call) + metadata = dict(service_accepted.metadata) + self.assertIn(client_metadata_key, metadata) + self.assertEqual(client_metadata_value, metadata[client_metadata_key]) + self.assertIn(client_binary_metadata_key, metadata) + self.assertEqual(client_binary_metadata_value, + metadata[client_binary_metadata_key]) server_call = service_accepted.service_acceptance.call server_call.accept(self.server_completion_queue, finish_tag) + server_call.add_metadata(server_leading_metadata_key, + server_leading_metadata_value) + server_call.add_metadata(server_leading_binary_metadata_key, + server_leading_binary_metadata_value) server_call.premetadata() metadata_accepted = self.client_completion_queue.get(_FUTURE) self.assertIsNotNone(metadata_accepted) self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind) self.assertEqual(metadata_tag, metadata_accepted.tag) - # TODO(nathaniel): Test transmission and reception of metadata. + metadata = dict(metadata_accepted.metadata) + self.assertIn(server_leading_metadata_key, metadata) + self.assertEqual(server_leading_metadata_value, + metadata[server_leading_metadata_key]) + self.assertIn(server_leading_binary_metadata_key, metadata) + self.assertEqual(server_leading_binary_metadata_value, + metadata[server_leading_binary_metadata_key]) for datum in test_data: client_call.write(datum, write_tag) @@ -194,6 +225,11 @@ class EchoTest(unittest.TestCase): self.assertEqual(read_tag, read_accepted.tag) self.assertIsNone(read_accepted.bytes) + server_call.add_metadata(server_trailing_metadata_key, + server_trailing_metadata_value) + server_call.add_metadata(server_trailing_binary_metadata_key, + server_trailing_binary_metadata_value) + server_call.status(_low.Status(_low.Code.OK, details), status_tag) server_terminal_event_one = self.server_completion_queue.get(_FUTURE) server_terminal_event_two = self.server_completion_queue.get(_FUTURE) @@ -229,6 +265,13 @@ class EchoTest(unittest.TestCase): self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind) self.assertEqual(finish_tag, finish_accepted.tag) self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status) + metadata = dict(finish_accepted.metadata) + self.assertIn(server_trailing_metadata_key, metadata) + self.assertEqual(server_trailing_metadata_value, + metadata[server_trailing_metadata_key]) + self.assertIn(server_trailing_binary_metadata_key, metadata) + self.assertEqual(server_trailing_binary_metadata_value, + metadata[server_trailing_binary_metadata_key]) server_timeout_none_event = self.server_completion_queue.get(0) self.assertIsNone(server_timeout_none_event) diff --git a/src/python/src/grpc/_adapter/_server.h b/src/python/src/grpc/_adapter/_server.h index 0c517e3715..4836bb638c 100644 --- a/src/python/src/grpc/_adapter/_server.h +++ b/src/python/src/grpc/_adapter/_server.h @@ -37,7 +37,10 @@ #include <Python.h> #include <grpc/grpc.h> -typedef struct { PyObject_HEAD grpc_server *c_server; } Server; +typedef struct { + PyObject_HEAD + grpc_server *c_server; +} Server; int pygrpc_add_server(PyObject *module); diff --git a/src/python/src/grpc/_adapter/_server_credentials.h b/src/python/src/grpc/_adapter/_server_credentials.h index 2e56efdcd9..6090404bd9 100644 --- a/src/python/src/grpc/_adapter/_server_credentials.h +++ b/src/python/src/grpc/_adapter/_server_credentials.h @@ -38,7 +38,8 @@ #include <grpc/grpc_security.h> typedef struct { - PyObject_HEAD grpc_server_credentials *c_server_credentials; + PyObject_HEAD + grpc_server_credentials *c_server_credentials; } ServerCredentials; PyTypeObject pygrpc_ServerCredentialsType; diff --git a/src/python/src/grpc/_adapter/rear.py b/src/python/src/grpc/_adapter/rear.py index f19321c426..2b93aa6331 100644 --- a/src/python/src/grpc/_adapter/rear.py +++ b/src/python/src/grpc/_adapter/rear.py @@ -93,7 +93,7 @@ class RearLink(base_interfaces.RearLink, activated.Activated): def __init__( self, host, port, pool, request_serializers, response_deserializers, secure, root_certificates, private_key, certificate_chain, - server_host_override=None): + metadata_transformer=None, server_host_override=None): """Constructor. Args: @@ -111,6 +111,9 @@ class RearLink(base_interfaces.RearLink, activated.Activated): key should be used. certificate_chain: The PEM-encoded certificate chain to use or None if no certificate chain should be used. + metadata_transformer: A function that given a metadata object produces + another metadata to be used in the underlying communication on the + wire. server_host_override: (For testing only) the target name used for SSL host name checking. """ @@ -134,6 +137,7 @@ class RearLink(base_interfaces.RearLink, activated.Activated): self._root_certificates = root_certificates self._private_key = private_key self._certificate_chain = certificate_chain + self._metadata_transformer = metadata_transformer self._server_host_override = server_host_override def _on_write_event(self, operation_id, event, rpc_state): @@ -243,6 +247,10 @@ class RearLink(base_interfaces.RearLink, activated.Activated): """ request_serializer = self._request_serializers[name] call = _low.Call(self._channel, name, self._host, time.time() + timeout) + if self._metadata_transformer is not None: + metadata = self._metadata_transformer([]) + for metadata_key, metadata_value in metadata: + call.add_metadata(metadata_key, metadata_value) call.invoke(self._completion_queue, operation_id, operation_id) outstanding = set(_INVOCATION_EVENT_KINDS) diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py index cc0b8ec9e8..35456d38c6 100644 --- a/src/python/src/grpc/early_adopter/implementations.py +++ b/src/python/src/grpc/early_adopter/implementations.py @@ -114,7 +114,7 @@ class _Stub(interfaces.Stub): def __init__( self, breakdown, host, port, secure, root_certificates, private_key, - certificate_chain, server_host_override=None): + certificate_chain, metadata_transformer=None, server_host_override=None): self._lock = threading.Lock() self._breakdown = breakdown self._host = host @@ -123,6 +123,7 @@ class _Stub(interfaces.Stub): self._root_certificates = root_certificates self._private_key = private_key self._certificate_chain = certificate_chain + self._metadata_transformer = metadata_transformer self._server_host_override = server_host_override self._pool = None @@ -141,6 +142,7 @@ class _Stub(interfaces.Stub): self._breakdown.request_serializers, self._breakdown.response_deserializers, self._secure, self._root_certificates, self._private_key, self._certificate_chain, + metadata_transformer=self._metadata_transformer, server_host_override=self._server_host_override) self._front.join_rear_link(self._rear_link) self._rear_link.join_fore_link(self._front) @@ -188,43 +190,11 @@ class _Stub(interfaces.Stub): raise AttributeError(attr) -def _build_stub( - service_name, methods, host, port, secure, root_certificates, private_key, - certificate_chain, server_host_override=None): - breakdown = _face_utilities.break_down_invocation(service_name, methods) - return _Stub( - breakdown, host, port, secure, root_certificates, private_key, - certificate_chain, server_host_override=server_host_override) - - -def _build_server(service_name, methods, port, private_key, certificate_chain): - breakdown = _face_utilities.break_down_service(service_name, methods) - return _Server(breakdown, port, private_key, certificate_chain) - - -def insecure_stub(service_name, methods, host, port): - """Constructs an insecure interfaces.Stub. - - Args: - service_name: The package-qualified full name of the service. - methods: A dictionary from RPC method name to - interfaces.RpcMethodInvocationDescription describing the RPCs to be - supported by the created stub. The RPC method names in the dictionary are - not qualified by the service name or decorated in any other way. - host: The host to which to connect for RPC service. - port: The port to which to connect for RPC service. - - Returns: - An interfaces.Stub affording RPC invocation. - """ - return _build_stub( - service_name, methods, host, port, False, None, None, None) - - -def secure_stub( - service_name, methods, host, port, root_certificates, private_key, - certificate_chain, server_host_override=None): - """Constructs an insecure interfaces.Stub. +def stub( + service_name, methods, host, port, metadata_transformer=None, secure=False, + root_certificates=None, private_key=None, certificate_chain=None, + server_host_override=None): + """Constructs an interfaces.Stub. Args: service_name: The package-qualified full name of the service. @@ -234,6 +204,10 @@ def secure_stub( not qualified by the service name or decorated in any other way. host: The host to which to connect for RPC service. port: The port to which to connect for RPC service. + metadata_transformer: A callable that given a metadata object produces + another metadata object to be used in the underlying communication on the + wire. + secure: Whether or not to construct the stub with a secure connection. root_certificates: The PEM-encoded root certificates or None to ask for them to be retrieved from a default location. private_key: The PEM-encoded private key to use or None if no private key @@ -246,32 +220,15 @@ def secure_stub( Returns: An interfaces.Stub affording RPC invocation. """ - return _build_stub( - service_name, methods, host, port, True, root_certificates, private_key, + breakdown = _face_utilities.break_down_invocation(service_name, methods) + return _Stub( + breakdown, host, port, secure, root_certificates, private_key, certificate_chain, server_host_override=server_host_override) -def insecure_server(service_name, methods, port): - """Constructs an insecure interfaces.Server. - - Args: - service_name: The package-qualified full name of the service. - methods: A dictionary from RPC method name to - interfaces.RpcMethodServiceDescription describing the RPCs to - be serviced by the created server. The RPC method names in the dictionary - are not qualified by the service name or decorated in any other way. - port: The desired port on which to serve or zero to ask for a port to - be automatically selected. - - Returns: - An interfaces.Server that will run with no security and - service unsecured raw requests. - """ - return _build_server(service_name, methods, port, None, None) - - -def secure_server(service_name, methods, port, private_key, certificate_chain): - """Constructs a secure interfaces.Server. +def server( + service_name, methods, port, private_key=None, certificate_chain=None): + """Constructs an interfaces.Server. Args: service_name: The package-qualified full name of the service. @@ -281,11 +238,12 @@ def secure_server(service_name, methods, port, private_key, certificate_chain): are not qualified by the service name or decorated in any other way. port: The port on which to serve or zero to ask for a port to be automatically selected. - private_key: A pem-encoded private key. - certificate_chain: A pem-encoded certificate chain. + private_key: A pem-encoded private key, or None for an insecure server. + certificate_chain: A pem-encoded certificate chain, or None for an insecure + server. Returns: An interfaces.Server that will serve secure traffic. """ - return _build_server( - service_name, methods, port, private_key, certificate_chain) + breakdown = _face_utilities.break_down_service(service_name, methods) + return _Server(breakdown, port, private_key, certificate_chain) diff --git a/src/python/src/grpc/early_adopter/implementations_test.py b/src/python/src/grpc/early_adopter/implementations_test.py index ae4adad90f..32b974724c 100644 --- a/src/python/src/grpc/early_adopter/implementations_test.py +++ b/src/python/src/grpc/early_adopter/implementations_test.py @@ -106,11 +106,11 @@ _TIMEOUT = 3 class EarlyAdopterImplementationsTest(unittest.TestCase): def setUp(self): - self.server = implementations.insecure_server( + self.server = implementations.server( SERVICE_NAME, _SERVICE_DESCRIPTIONS, 0) self.server.start() port = self.server.port() - self.stub = implementations.insecure_stub( + self.stub = implementations.stub( SERVICE_NAME, _INVOCATION_DESCRIPTIONS, 'localhost', port) def tearDown(self): diff --git a/src/python/src/setup.py b/src/python/src/setup.py index bd70634b8f..32ac41e285 100644 --- a/src/python/src/setup.py +++ b/src/python/src/setup.py @@ -30,6 +30,8 @@ """A setup module for the GRPC Python package.""" from distutils import core as _core +import setuptools +import sys _EXTENSION_SOURCES = ( 'grpc/_adapter/_c.c', @@ -49,8 +51,9 @@ _EXTENSION_INCLUDE_DIRECTORIES = ( _EXTENSION_LIBRARIES = ( 'grpc', 'gpr', - 'rt', ) +if not "darwin" in sys.platform: + _EXTENSION_LIBRARIES += ('rt',) _EXTENSION_MODULE = _core.Extension( 'grpc._adapter._c', sources=list(_EXTENSION_SOURCES), @@ -80,7 +83,15 @@ _PACKAGE_DIRECTORIES = { 'grpc.framework': 'grpc/framework', } -_core.setup( - name='grpc-2015', version='0.4.0', - ext_modules=[_EXTENSION_MODULE], packages=list(_PACKAGES), - package_dir=_PACKAGE_DIRECTORIES) +setuptools.setup( + name='grpcio', + version='0.5.0a0', + ext_modules=[_EXTENSION_MODULE], + packages=list(_PACKAGES), + package_dir=_PACKAGE_DIRECTORIES, + install_requires=[ + 'enum34==1.0.4', + 'futures==2.2.0', + 'protobuf==3.0.0-alpha-1' + ] +) diff --git a/src/ruby/Rakefile b/src/ruby/Rakefile index b27305d16c..afb354e922 100755 --- a/src/ruby/Rakefile +++ b/src/ruby/Rakefile @@ -2,14 +2,17 @@ require 'rake/extensiontask' require 'rspec/core/rake_task' require 'rubocop/rake_task' +require 'bundler/gem_tasks' -desc 'Run Rubocop to check for style violations' +# Add rubocop style checking tasks RuboCop::RakeTask.new +# Add the extension compiler task Rake::ExtensionTask.new 'grpc' do |ext| ext.lib_dir = File.join('lib', 'grpc') end +# Define the test suites SPEC_SUITES = [ { id: :wrapper, title: 'wrapper layer', files: %w(spec/*.rb) }, { id: :idiomatic, title: 'idiomatic layer', dir: %w(spec/generic), @@ -19,36 +22,34 @@ SPEC_SUITES = [ { id: :server, title: 'rpc server thread tests', dir: %w(spec/generic), tag: 'server' } ] +namespace :suite do + SPEC_SUITES.each do |suite| + desc "Run all specs in the #{suite[:title]} spec suite" + RSpec::Core::RakeTask.new(suite[:id]) do |t| + spec_files = [] + suite[:files].each { |f| spec_files += Dir[f] } if suite[:files] + + if suite[:dir] + suite[:dir].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] } + end + helper = 'spec/spec_helper.rb' + spec_files << helper unless spec_files.include?(helper) -desc 'Run all RSpec tests' -namespace :spec do - namespace :suite do - SPEC_SUITES.each do |suite| - desc "Run all specs in #{suite[:title]} spec suite" - RSpec::Core::RakeTask.new(suite[:id]) do |t| - spec_files = [] - suite[:files].each { |f| spec_files += Dir[f] } if suite[:files] - - if suite[:dirs] - suite[:dirs].each { |f| spec_files += Dir["#{f}/**/*_spec.rb"] } - end - - t.pattern = spec_files - t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag] - if suite[:tags] - t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ') - end + t.pattern = spec_files + t.rspec_opts = "--tag #{suite[:tag]}" if suite[:tag] + if suite[:tags] + t.rspec_opts = suite[:tags].map { |x| "--tag #{x}" }.join(' ') end end end end -desc 'Compiles the extension then runs all the tests' -task :all +# Define dependencies between the suites. +task 'suite:wrapper' => [:compile, :rubocop] +task 'suite:idiomatic' => 'suite:wrapper' +task 'suite:bidi' => 'suite:wrapper' +task 'suite:server' => 'suite:wrapper' +desc 'Compiles the gRPC extension then runs all the tests' +task all: ['suite:idiomatic', 'suite:bidi', 'suite:server'] task default: :all -task 'spec:suite:wrapper' => [:compile, :rubocop] -task 'spec:suite:idiomatic' => 'spec:suite:wrapper' -task 'spec:suite:bidi' => 'spec:suite:wrapper' -task 'spec:suite:server' => 'spec:suite:wrapper' -task all: ['spec:suite:idiomatic', 'spec:suite:bidi', 'spec:suite:server'] diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb index 6ea0831a2e..69076b4c6e 100644 --- a/src/ruby/lib/grpc/generic/service.rb +++ b/src/ruby/lib/grpc/generic/service.rb @@ -176,25 +176,26 @@ module GRPC unmarshal = desc.unmarshal_proc(:output) route = "/#{route_prefix}/#{name}" if desc.request_response? - define_method(mth_name) do |req, deadline = nil| + define_method(mth_name) do |req, deadline = nil, **kw| logger.debug("calling #{@host}:#{route}") - request_response(route, req, marshal, unmarshal, deadline) + request_response(route, req, marshal, unmarshal, deadline, **kw) end elsif desc.client_streamer? - define_method(mth_name) do |reqs, deadline = nil| + define_method(mth_name) do |reqs, deadline = nil, **kw| logger.debug("calling #{@host}:#{route}") - client_streamer(route, reqs, marshal, unmarshal, deadline) + client_streamer(route, reqs, marshal, unmarshal, deadline, **kw) end elsif desc.server_streamer? - define_method(mth_name) do |req, deadline = nil, &blk| + define_method(mth_name) do |req, deadline = nil, **kw, &blk| logger.debug("calling #{@host}:#{route}") - server_streamer(route, req, marshal, unmarshal, deadline, + server_streamer(route, req, marshal, unmarshal, deadline, **kw, &blk) end else # is a bidi_stream - define_method(mth_name) do |reqs, deadline = nil, &blk| + define_method(mth_name) do |reqs, deadline = nil, **kw, &blk| logger.debug("calling #{@host}:#{route}") - bidi_streamer(route, reqs, marshal, unmarshal, deadline, &blk) + bidi_streamer(route, reqs, marshal, unmarshal, deadline, **kw, + &blk) end end end diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index 513a53724f..bfd0cbb393 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -29,5 +29,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '0.5.0' + VERSION = '0.6.0' end diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb index 8914225b55..96e07cacb4 100644 --- a/src/ruby/spec/generic/active_call_spec.rb +++ b/src/ruby/spec/generic/active_call_spec.rb @@ -67,7 +67,7 @@ describe GRPC::ActiveCall do end describe '#multi_req_view' do - xit 'exposes a fixed subset of the ActiveCall methods' do + it 'exposes a fixed subset of the ActiveCall methods' do want = %w(cancelled, deadline, each_remote_read, metadata, shutdown) v = @client_call.multi_req_view want.each do |w| @@ -77,7 +77,7 @@ describe GRPC::ActiveCall do end describe '#single_req_view' do - xit 'exposes a fixed subset of the ActiveCall methods' do + it 'exposes a fixed subset of the ActiveCall methods' do want = %w(cancelled, deadline, metadata, shutdown) v = @client_call.single_req_view want.each do |w| diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb index 73f2d37e30..0c98fc40d9 100644 --- a/src/ruby/spec/generic/client_stub_spec.rb +++ b/src/ruby/spec/generic/client_stub_spec.rb @@ -384,13 +384,7 @@ describe 'ClientStub' do th.join end - # disabled because an unresolved wire-protocol implementation feature - # - # - servers should be able initiate messaging, however, as it stand - # servers don't know if all the client metadata has been sent until - # they receive a message from the client. Without receiving all the - # metadata, the server does not accept the call, so this test hangs. - xit 'supports a server-initiated ping pong', bidi: true do + it 'supports a server-initiated ping pong', bidi: true do server_port = create_test_server host = "localhost:#{server_port}" th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, false) diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index f3b89b5895..34e5cdcd04 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -81,14 +81,17 @@ EchoStub = EchoService.rpc_stub_class class SlowService include GRPC::GenericService rpc :an_rpc, EchoMsg, EchoMsg + attr_reader :received_md, :delay def initialize(_default_var = 'ignored') + @delay = 0.25 + @received_md = [] end - def an_rpc(req, _call) - delay = 0.25 - logger.info("starting a slow #{delay} rpc") - sleep delay + def an_rpc(req, call) + logger.info("starting a slow #{@delay} rpc") + sleep @delay + @received_md << call.metadata unless call.metadata.nil? req # send back the req as the response end end @@ -354,6 +357,37 @@ describe GRPC::RpcServer do t.join end + it 'should receive metadata when a deadline is specified', server: true do + service = SlowService.new + @srv.handle(service) + t = Thread.new { @srv.run } + @srv.wait_till_running + req = EchoMsg.new + stub = SlowStub.new(@host, **@client_opts) + deadline = service.delay + 0.5 # wait for long enough + expect(stub.an_rpc(req, deadline, k1: 'v1', k2: 'v2')).to be_a(EchoMsg) + wanted_md = [{ 'k1' => 'v1', 'k2' => 'v2' }] + expect(service.received_md).to eq(wanted_md) + @srv.stop + t.join + end + + it 'should not receive metadata if the client times out', server: true do + service = SlowService.new + @srv.handle(service) + t = Thread.new { @srv.run } + @srv.wait_till_running + req = EchoMsg.new + stub = SlowStub.new(@host, **@client_opts) + deadline = 0.1 # too short for SlowService to respond + blk = proc { stub.an_rpc(req, deadline, k1: 'v1', k2: 'v2') } + expect(&blk).to raise_error GRPC::BadStatus + wanted_md = [] + expect(service.received_md).to eq(wanted_md) + @srv.stop + t.join + end + it 'should receive updated metadata', server: true do service = EchoService.new @srv.handle(service) diff --git a/templates/BUILD.template b/templates/BUILD.template new file mode 100644 index 0000000000..8303b9f8e9 --- /dev/null +++ b/templates/BUILD.template @@ -0,0 +1,110 @@ +# GRPC Bazel BUILD file. +# This currently builds C and C++ code. + +# 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. + +licenses(["notice"]) # 3-clause BSD + +package(default_visibility = ["//visibility:public"]) + +<%! +def get_deps(target_dict): + deps = [] + if target_dict.get('secure', 'no') == 'yes': + deps = [ + "//external:libssl", + ] + if target_dict.get('build', None) == 'protoc': + deps.append("//external:protobuf_compiler") + if target_dict['name'] == 'grpc++_unsecure' or target_dict['name'] == 'grpc++': + deps.append("//external:protobuf_clib") + for d in target_dict.get('deps', []): + if d.find('//') == 0 or d[0] == ':': + deps.append(d) + else: + deps.append(':%s' % (d)) + return deps +%> + +% for lib in libs: +% if lib.build != "private": +${cc_library(lib)} +% endif +% endfor + +% for tgt in targets: +% if tgt.build == 'protoc': +${cc_binary(tgt)} +% endif +% endfor + +<%def name="cc_library(lib)"> +cc_library( + name = "${lib.name}", + srcs = [ +% for hdr in lib.get("headers", []): + "${hdr}", +% endfor +% for src in lib.src: + "${src}", +% endfor + ], + hdrs = [ +% for hdr in lib.get("public_headers", []): + "${hdr}", +% endfor + ], + includes = [ + "include", + ".", + ], + deps = [ +% for dep in get_deps(lib): + "${dep}", +% endfor + ], +) +</%def> + +<%def name="cc_binary(tgt)"> +cc_binary( + name = "${tgt.name}", + srcs = [ +% for src in tgt.src: + "${src}", +% endfor + ], + deps = [ +% for dep in get_deps(tgt): + "${dep}", +% endfor + ], +) +</%def> diff --git a/templates/Makefile.template b/templates/Makefile.template index 36d11425df..2cfbfa36ec 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -35,17 +35,11 @@ proto_re = re.compile('(.*)\\.proto') - def excluded(filename, exclude_res): - for r in exclude_res: - if r.match(filename): - return True - return False - def proto_to_cc(filename): m = proto_re.match(filename) if not m: return filename - return '$(GENDIR)/' + m.group(1) + '.pb.cc' + return '$(GENDIR)/' + m.group(1) + '.pb.cc $(GENDIR)/' + m.group(1) + '.grpc.pb.cc' %> @@ -111,6 +105,15 @@ CPPFLAGS_dbg = -O0 LDFLAGS_dbg = DEFINES_dbg = _DEBUG DEBUG +VALID_CONFIG_mutrace = 1 +CC_mutrace = $(DEFAULT_CC) +CXX_mutrace = $(DEFAULT_CXX) +LD_mutrace = $(DEFAULT_CC) +LDXX_mutrace = $(DEFAULT_CXX) +CPPFLAGS_mutrace = -O0 +LDFLAGS_mutrace = -rdynamic +DEFINES_mutrace = _DEBUG DEBUG + VALID_CONFIG_valgrind = 1 REQUIRE_CUSTOM_LIBRARIES_valgrind = 1 CC_valgrind = $(DEFAULT_CC) @@ -235,7 +238,6 @@ ifeq ($(HAS_CXX11),true) CXXFLAGS += -std=c++11 else CXXFLAGS += -std=c++0x -DEFINES += GRPC_OLD_CXX endif CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter LDFLAGS += -g @@ -832,11 +834,17 @@ endif % for p in protos: ifeq ($(NO_PROTOC),true) $(GENDIR)/${p}.pb.cc: protoc_dep_error +$(GENDIR)/${p}.grpc.pb.cc: protoc_dep_error else $(GENDIR)/${p}.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(E) "[PROTOC] Generating protobuf CC file from $<" $(Q) mkdir -p `dirname $@` - $(Q) $(PROTOC) --cpp_out=$(GENDIR) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) --cpp_out=$(GENDIR) $< + +$(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) + $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< endif % endfor @@ -918,10 +926,11 @@ ifeq ($(SYSTEM),MINGW32) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/${lib.name}.$(SHARED_EXT) $(prefix)/lib/${lib.name}.$(SHARED_EXT) $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}-imp.a $(prefix)/lib/lib${lib.name}-imp.a else -ifneq ($(SYSTEM),Darwin) $(E) "[INSTALL] Installing lib${lib.name}.$(SHARED_EXT)" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so.${settings.version.major} $(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so endif endif @@ -1158,7 +1167,7 @@ ${out_libbase}.$(SHARED_EXT): $(LIB${lib.name.upper()}_OBJS) ${lib_deps} $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs} + $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name lib${lib.name}.$(SHARED_EXT) -dynamiclib -o ${out_libbase}.$(SHARED_EXT) ${common}${libs} else $(Q) ${ld} $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,lib${lib.name}.so.${settings.version.major} -o ${out_libbase}.$(SHARED_EXT) ${common}${libs} $(Q) ln -sf lib${lib.name}.$(SHARED_EXT) ${out_libbase}.so.${settings.version.major} diff --git a/templates/vsprojects/vs2010/Grpc.mak.template b/templates/vsprojects/vs2010/Grpc.mak.template new file mode 100644 index 0000000000..8e1b33bba7 --- /dev/null +++ b/templates/vsprojects/vs2010/Grpc.mak.template @@ -0,0 +1,107 @@ +# 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. +<%! + import re +%>\ +<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\ +<% + allowed_dependencies = set(['gpr', 'grpc', 'gpr_test_util', 'grpc_test_util']) + buildable_targets = [ target for target in targets if set(target.deps).issubset(allowed_dependencies) and all([src.endswith('.c') for src in target.src])] + test_targets = [ target for target in buildable_targets if target.name.endswith('_test') ] +%>\ +# NMake file to build secondary gRPC targets on Windows. +# Use grpc.sln to solution to build the gRPC libraries. + +OUT_DIR=test_bin + +CC=cl.exe +LINK=link.exe + +INCLUDES=/I..\.. /I..\..\include /I..\..\third_party\zlib /I..\third_party /I..\..\third_party\openssl\inc32 +DEFINES=/D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /D _CRT_SECURE_NO_WARNINGS +CFLAGS=/c $(INCLUDES) /nologo /Z7 /W3 /WX- /sdl $(DEFINES) /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- +LFLAGS=/DEBUG /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 + +OPENSSL_LIBS=..\..\third_party\openssl\out32\ssleay32.lib ..\..\third_party\openssl\out32\libeay32.lib +WINSOCK_LIBS=ws2_32.lib +ZLIB_LIBS=Debug\zlibwapi.lib +LIBS=$(OPENSSL_LIBS) $(WINSOCK_LIBS) $(ZLIB_LIBS) + +gpr_test_util: + MSBuild.exe gpr_test_util.vcxproj /p:Configuration=Debug + +grpc_test_util: + MSBuild.exe grpc_test_util.vcxproj /p:Configuration=Debug + +$(OUT_DIR): + mkdir $(OUT_DIR) + +buildtests: \ +% for target in test_targets: +${target.name}.exe \ +% endfor + + echo All tests built. + +test: \ +% for target in test_targets: +${target.name} \ +% endfor + + echo All tests ran. + +test_gpr: \ +% for target in [ tgt for tgt in test_targets if tgt.name.startswith('gpr_')]: +${target.name} \ +% endfor + + echo All tests ran. + +% for target in buildable_targets: +${target.name}.exe: grpc_test_util + echo Building ${target.name} + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ \ +%for source in target.src: +..\..\${to_windows_path(source)} \ +%endfor + + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\${target.name}.exe" \ +%for dep in target.deps: +Debug\${dep}.lib \ +%endfor +$(LIBS) \ +%for source in target.src: +$(OUT_DIR)\${re.search('([^/]+)\.c$', source).group(1)}.obj \ +%endfor + +${target.name}: ${target.name}.exe + echo Running ${target.name} + $(OUT_DIR)\${target.name}.exe + +% endfor diff --git a/templates/vsprojects/vs2013/gpr_shared.vcxproj.filters.template b/templates/vsprojects/vs2010/gpr.vcxproj.filters.template index c8b2ce099e..c8b2ce099e 100644 --- a/templates/vsprojects/vs2013/gpr_shared.vcxproj.filters.template +++ b/templates/vsprojects/vs2010/gpr.vcxproj.filters.template diff --git a/templates/vsprojects/vs2010/gpr.vcxproj.template b/templates/vsprojects/vs2010/gpr.vcxproj.template new file mode 100644 index 0000000000..c478aadcdd --- /dev/null +++ b/templates/vsprojects/vs2010/gpr.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('gpr', libs, targets)} diff --git a/templates/vsprojects/vs2010/gpr_test_util.vcxproj.template b/templates/vsprojects/vs2010/gpr_test_util.vcxproj.template new file mode 100644 index 0000000000..1f1bc0a5fb --- /dev/null +++ b/templates/vsprojects/vs2010/gpr_test_util.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('gpr_test_util', libs, targets)}
\ No newline at end of file diff --git a/templates/vsprojects/vs2010/grpc++.vcxproj.filters.template b/templates/vsprojects/vs2010/grpc++.vcxproj.filters.template new file mode 100644 index 0000000000..d74cce8c78 --- /dev/null +++ b/templates/vsprojects/vs2010/grpc++.vcxproj.filters.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj.filters_defs.include" import="gen_filters"/>\ +${gen_filters('grpc++', libs, targets)} diff --git a/templates/vsprojects/vs2010/grpc++.vcxproj.template b/templates/vsprojects/vs2010/grpc++.vcxproj.template new file mode 100644 index 0000000000..93994bb392 --- /dev/null +++ b/templates/vsprojects/vs2010/grpc++.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('grpc++', libs, targets)}
\ No newline at end of file diff --git a/templates/vsprojects/vs2010/grpc.sln.template b/templates/vsprojects/vs2010/grpc.sln.template new file mode 100644 index 0000000000..47aa03ca41 --- /dev/null +++ b/templates/vsprojects/vs2010/grpc.sln.template @@ -0,0 +1,59 @@ +## Template for Visual Studio solution +## based on http://msdn.microsoft.com/en-us/library/bb165951(v=vs.90).aspx +## NOTE: tabs in this file are needed by Visual Studio to correctly interpret +## the file. +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +<% +## Visual Studio uses GUIDs for project types +## http://msdn.microsoft.com/en-us/library/hb23x61k%28v=vs.80%29.aspx +cpp_proj_type = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}" +%>\ +% for project in vsprojects: +Project("${cpp_proj_type}") = "${project.name}", "${project.name}.vcxproj", "${project.vs_project_guid}" + % if project.get('deps', None): + ProjectSection(ProjectDependencies) = postProject + % for dep in project.get('deps', []): + ${vsproject_dict[dep].vs_project_guid} = ${vsproject_dict[dep].vs_project_guid} + % endfor + EndProjectSection + % endif +EndProject +% endfor +Project("${cpp_proj_type}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}" +EndProject +Project("${cpp_proj_type}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution +% for project in vsprojects: + ${project.vs_project_guid}.Debug|Win32.ActiveCfg = Debug|Win32 + ${project.vs_project_guid}.Debug|Win32.Build.0 = Debug|Win32 + ${project.vs_project_guid}.Release|Win32.ActiveCfg = Release|Win32 + ${project.vs_project_guid}.Release|Win32.Build.0 = Release|Win32 +% endfor + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.Build.0 = Debug|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.ActiveCfg = Release|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.Build.0 = Release|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.Build.0 = Debug|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.ActiveCfg = Release|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.Build.0 = Release|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.Build.0 = Debug|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.ActiveCfg = Release|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/templates/vsprojects/vs2013/grpc_shared.vcxproj.filters.template b/templates/vsprojects/vs2010/grpc.vcxproj.filters.template index b8e91bd61c..b8e91bd61c 100644 --- a/templates/vsprojects/vs2013/grpc_shared.vcxproj.filters.template +++ b/templates/vsprojects/vs2010/grpc.vcxproj.filters.template diff --git a/templates/vsprojects/vs2010/grpc.vcxproj.template b/templates/vsprojects/vs2010/grpc.vcxproj.template new file mode 100644 index 0000000000..3de6453f52 --- /dev/null +++ b/templates/vsprojects/vs2010/grpc.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('grpc', libs, targets)}
\ No newline at end of file diff --git a/templates/vsprojects/vs2010/grpc_csharp_ext.vcxproj.template b/templates/vsprojects/vs2010/grpc_csharp_ext.vcxproj.template new file mode 100644 index 0000000000..84aa50209a --- /dev/null +++ b/templates/vsprojects/vs2010/grpc_csharp_ext.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('grpc_csharp_ext', libs, targets)} diff --git a/templates/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj.template b/templates/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj.template new file mode 100644 index 0000000000..193a2cd13f --- /dev/null +++ b/templates/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('grpc_csharp_ext', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{C26D04A8-37C6-44C7-B458-906C9FCE928C}', additional_props = ['winsock', 'ssl'])} diff --git a/templates/vsprojects/vs2010/grpc_test_util.vcxproj.template b/templates/vsprojects/vs2010/grpc_test_util.vcxproj.template new file mode 100644 index 0000000000..72e625d9b9 --- /dev/null +++ b/templates/vsprojects/vs2010/grpc_test_util.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('grpc_test_util', libs, targets)}
\ No newline at end of file diff --git a/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.filters.template b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.filters.template new file mode 100644 index 0000000000..ef918922ef --- /dev/null +++ b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.filters.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj.filters_defs.include" import="gen_filters"/>\ +${gen_filters('grpc_unsecure', libs, targets)} diff --git a/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.template b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.template new file mode 100644 index 0000000000..4f62b85a85 --- /dev/null +++ b/templates/vsprojects/vs2010/grpc_unsecure.vcxproj.template @@ -0,0 +1,2 @@ +<%namespace file="vcxproj_defs.include" import="gen_project"/>\ +${gen_project('grpc_unsecure', libs, targets)}
\ No newline at end of file diff --git a/templates/vsprojects/vs2010/vcxproj.filters_defs.include b/templates/vsprojects/vs2010/vcxproj.filters_defs.include new file mode 100644 index 0000000000..539ae932f1 --- /dev/null +++ b/templates/vsprojects/vs2010/vcxproj.filters_defs.include @@ -0,0 +1,64 @@ +<%! + import re + import hashlib + + def calc_to_filter(path): + return '\\'.join(path.split('/')[:-1]) +%>\ +<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\ +<%def name="to_filter(path)">${calc_to_filter(path)}</%def>\ +<%def name="filter_to_guid(proj, filter)">${re.sub('(........)(....)(....)(....)', r'\1-\2-\3-\4-', hashlib.md5(''.join([filter, proj])).hexdigest())}</%def>\ +<%def name="gen_filters(name, libs, targets)">\ +% for project in vsprojects: + % if project.name == name: +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + % if project.get('src',[]): + <ItemGroup> + % for src_name in project.src: + <ClCompile Include="..\..\${to_windows_path(src_name)}"> + <Filter>${to_filter(src_name)}</Filter> + </ClCompile> + % endfor + </ItemGroup> + % endif + % if project.get('public_headers',[]): + <ItemGroup> + % for public_header in project.public_headers: + <ClInclude Include="..\..\${to_windows_path(public_header)}"> + <Filter>${to_filter(public_header)}</Filter> + </ClInclude> + % endfor + </ItemGroup> + % endif + % if project.get('headers',[]): + <ItemGroup> + % for header in project.headers: + <ClInclude Include="..\..\${to_windows_path(header)}"> + <Filter>${to_filter(header)}</Filter> + </ClInclude> + % endfor + </ItemGroup> + % endif +<% + filters = set() + files = project.get('src', []) + project.get('public_headers', []) + project.get('headers', []) + for file in files: + filter = calc_to_filter(file) + paths = filter.split('\\') + for i in range(len(paths)): + filters.add('\\'.join(paths[:i + 1])) + + filters = sorted(filters) +%> + <ItemGroup> + % for filter in filters: + <Filter Include="${filter}"> + <UniqueIdentifier>{${filter_to_guid(project.name, filter)}}</UniqueIdentifier> + </Filter> + % endfor + </ItemGroup> +</Project> + % endif +% endfor +</%def>\
\ No newline at end of file diff --git a/templates/vsprojects/vs2010/vcxproj_defs.include b/templates/vsprojects/vs2010/vcxproj_defs.include new file mode 100644 index 0000000000..8fd78a34dc --- /dev/null +++ b/templates/vsprojects/vs2010/vcxproj_defs.include @@ -0,0 +1,131 @@ +<%def name="to_windows_path(path)">${path.replace('/','\\')}</%def>\ +<%def name="get_subsystem(is_library)">${'Windows' if is_library else 'Console'}</%def>\ +<%def name="gen_project(name, libs, targets, configuration_type = 'StaticLibrary', project_guid = None, additional_props = [], depends_on_zlib = False)">\ +% for project in vsprojects: + % if project.name == name: +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>${project_guid if project_guid else project.vs_project_guid}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>${configuration_type}</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>${configuration_type}</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + % for prop in additional_props: + <Import Project="${prop}.props" /> + % endfor + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + % for prop in additional_props: + <Import Project="${prop}.props" /> + % endfor + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>${name}</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>${name}</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>${get_subsystem(project.is_library)}</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>${get_subsystem(project.is_library)}</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + % if project.get('public_headers',[]): + <ItemGroup> + % for public_header in project.public_headers: + <ClInclude Include="..\..\${to_windows_path(public_header)}" /> + % endfor + </ItemGroup> + % endif + % if project.get('headers',[]): + <ItemGroup> + % for header in project.headers: + <ClInclude Include="..\..\${to_windows_path(header)}" /> + % endfor + </ItemGroup> + % endif + % if project.get('src',[]): + <ItemGroup> + % for src_name in project.src: + <ClCompile Include="..\..\${to_windows_path(src_name)}"> + </ClCompile> + % endfor + </ItemGroup> + % endif + % if project.get('deps',[]): + <ItemGroup> + % for dep in project.deps: + <ProjectReference Include="${dep}.vcxproj"> + <Project>${vsproject_dict[dep].vs_project_guid}</Project> + </ProjectReference> + % endfor + % if depends_on_zlib: + <ProjectReference Include="third_party\zlibvc.vcxproj"> + <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project> + </ProjectReference> + % endif + </ItemGroup> + % endif + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> + % endif +% endfor +</%def>\
\ No newline at end of file diff --git a/templates/vsprojects/vs2013/gpr_shared.vcxproj.template b/templates/vsprojects/vs2013/gpr_shared.vcxproj.template deleted file mode 100644 index d1b1dd3c8b..0000000000 --- a/templates/vsprojects/vs2013/gpr_shared.vcxproj.template +++ /dev/null @@ -1,2 +0,0 @@ -<%namespace file="vcxproj_defs.include" import="gen_project"/>\ -${gen_project('gpr', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}')} diff --git a/templates/vsprojects/vs2013/grpc.sln.template b/templates/vsprojects/vs2013/grpc.sln.template index d17f4a31aa..2b0f76b90d 100644 --- a/templates/vsprojects/vs2013/grpc.sln.template +++ b/templates/vsprojects/vs2013/grpc.sln.template @@ -23,10 +23,6 @@ Project("${cpp_proj_type}") = "${project.name}", "${project.name}.vcxproj", "${p % endif EndProject % endfor -Project("${cpp_proj_type}") = "gpr_shared", "gpr_shared.vcxproj", "{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}" -EndProject -Project("${cpp_proj_type}") = "grpc_shared", "grpc_shared.vcxproj", "{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}" -EndProject Project("${cpp_proj_type}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}" EndProject Project("${cpp_proj_type}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" diff --git a/templates/vsprojects/vs2013/grpc_shared.vcxproj.template b/templates/vsprojects/vs2013/grpc_shared.vcxproj.template deleted file mode 100644 index 890189c28d..0000000000 --- a/templates/vsprojects/vs2013/grpc_shared.vcxproj.template +++ /dev/null @@ -1,2 +0,0 @@ -<%namespace file="vcxproj_defs.include" import="gen_project"/>\ -${gen_project('grpc', libs, targets, configuration_type = 'DynamicLibrary', project_guid = '{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}', additional_props = ['ssl', 'winsock'], depends_on_zlib = True)} diff --git a/test/compiler/python_plugin_test.py b/test/compiler/python_plugin_test.py index 3d2f117b0d..ad3bebac30 100644 --- a/test/compiler/python_plugin_test.py +++ b/test/compiler/python_plugin_test.py @@ -177,7 +177,7 @@ def _CreateService(test_pb2, delay): servicer = Servicer() server = getattr( - test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, 0, None, None) + test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, 0) with server: port = server.port() stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)('localhost', port) diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index e15fa7fcd9..592dfd415f 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -51,10 +51,11 @@ static void *tag(gpr_intptr t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, const char *test_name, + cancellation_mode mode, grpc_channel_args *client_args, grpc_channel_args *server_args) { grpc_end2end_test_fixture f; - gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + gpr_log(GPR_INFO, "%s/%s/%s", test_name, config.name, mode.name); f = config.create_fixture(client_args, server_args); config.init_client(&f, client_args); config.init_server(&f, server_args); @@ -109,7 +110,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config, grpc_op ops[6]; grpc_op *op; grpc_call *c; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = + begin_test(config, __FUNCTION__, mode, NULL, NULL); gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); grpc_metadata_array initial_metadata_recv; diff --git a/test/core/end2end/tests/cancel_test_helpers.h b/test/core/end2end/tests/cancel_test_helpers.h index f2581dc32f..0d680fcfe1 100644 --- a/test/core/end2end/tests/cancel_test_helpers.h +++ b/test/core/end2end/tests/cancel_test_helpers.h @@ -35,6 +35,7 @@ #define GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H typedef struct { + const char *name; grpc_call_error (*initiate_cancel)(grpc_call *call); grpc_status_code expect_status; const char *expect_details; @@ -45,7 +46,9 @@ static grpc_call_error wait_for_deadline(grpc_call *call) { } static const cancellation_mode cancellation_modes[] = { - {grpc_call_cancel, GRPC_STATUS_CANCELLED, ""}, - {wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"}, }; + {"cancel", grpc_call_cancel, GRPC_STATUS_CANCELLED, ""}, + {"deadline", wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, + "Deadline Exceeded"}, +}; -#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */ +#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */ diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index 708444a287..1c02c4b2f8 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -61,14 +61,14 @@ static void on_connect(void *arg, grpc_endpoint *tcp) { static void test_no_op(void) { grpc_tcp_server *s = grpc_tcp_server_create(); - grpc_tcp_server_destroy(s); + grpc_tcp_server_destroy(s, NULL, NULL); } static void test_no_op_with_start(void) { grpc_tcp_server *s = grpc_tcp_server_create(); LOG_TEST(); grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); - grpc_tcp_server_destroy(s); + grpc_tcp_server_destroy(s, NULL, NULL); } static void test_no_op_with_port(void) { @@ -81,7 +81,7 @@ static void test_no_op_with_port(void) { GPR_ASSERT( grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr))); - grpc_tcp_server_destroy(s); + grpc_tcp_server_destroy(s, NULL, NULL); } static void test_no_op_with_port_and_start(void) { @@ -96,7 +96,7 @@ static void test_no_op_with_port_and_start(void) { grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); - grpc_tcp_server_destroy(s); + grpc_tcp_server_destroy(s, NULL, NULL); } static void test_connect(int n) { @@ -145,7 +145,7 @@ static void test_connect(int n) { gpr_mu_unlock(&mu); - grpc_tcp_server_destroy(s); + grpc_tcp_server_destroy(s, NULL, NULL); } int main(int argc, char **argv) { diff --git a/test/core/support/thd_test.c b/test/core/support/thd_test.c index c03a905d2a..bb3d54a262 100644 --- a/test/core/support/thd_test.c +++ b/test/core/support/thd_test.c @@ -60,12 +60,16 @@ static void thd_body(void *v) { gpr_mu_unlock(&t->mu); } +static void thd_body_joinable(void *v) { } + /* Test that we can create a number of threads and wait for them. */ static void test(void) { int i; gpr_thd_id thd; + gpr_thd_id thds[1000]; struct test t; int n = 1000; + gpr_thd_options options = gpr_thd_options_default(); gpr_mu_init(&t.mu); gpr_cv_init(&t.done_cv); t.n = n; @@ -79,6 +83,13 @@ static void test(void) { } gpr_mu_unlock(&t.mu); GPR_ASSERT(t.n == 0); + gpr_thd_options_set_joinable(&options); + for (i = 0; i < n; i++) { + GPR_ASSERT(gpr_thd_new(&thds[i], &thd_body_joinable, NULL, &options)); + } + for (i = 0; i < n; i++) { + gpr_thd_join(thds[i]); + } } /* ------------------------------------------------- */ diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c index c5882af966..d591e43faa 100644 --- a/test/core/tsi/transport_security_test.c +++ b/test/core/tsi/transport_security_test.c @@ -39,10 +39,15 @@ #include <grpc/support/log.h> #include <grpc/support/useful.h> +#include <openssl/crypto.h> + #include "src/core/support/string.h" #include "src/core/tsi/ssl_transport_security.h" #include "test/core/util/test_config.h" +/* Currently points to 1.0.2a. */ +#define GRPC_MIN_OPENSSL_VERSION_NUMBER 0x1000201fL + typedef struct { /* 1 if success, 0 if failure. */ int expected; @@ -296,8 +301,13 @@ static void test_peer_matches_name(void) { } } +static void test_openssl_version(void) { + GPR_ASSERT(OPENSSL_VERSION_NUMBER >= GRPC_MIN_OPENSSL_VERSION_NUMBER); +} + int main(int argc, char **argv) { grpc_test_init(argc, argv); test_peer_matches_name(); + test_openssl_version(); return 0; } diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c index 36f13e1b51..7467c2f9ea 100644 --- a/test/core/util/port_posix.c +++ b/test/core/util/port_posix.c @@ -32,7 +32,8 @@ */ #include <grpc/support/port_platform.h> -#ifdef GPR_POSIX_SOCKET +#include "test/core/util/test_config.h" +#if defined(GPR_POSIX_SOCKET) && defined(GRPC_TEST_PICK_PORT) #include "test/core/util/port.h" @@ -125,7 +126,7 @@ int grpc_pick_unused_port(void) { } else { port = 0; } - + if (!is_port_available(&port, is_tcp)) { continue; } @@ -155,4 +156,4 @@ int grpc_pick_unused_port_or_die(void) { return port; } -#endif /* GPR_POSIX_SOCKET */ +#endif /* GPR_POSIX_SOCKET && GRPC_TEST_PICK_PORT */ diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h index 668a069f26..0b3c54373d 100644 --- a/test/core/util/test_config.h +++ b/test/core/util/test_config.h @@ -59,6 +59,10 @@ extern "C" { gpr_time_add(gpr_now(), \ gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e3 * (x))) +#ifndef GRPC_TEST_CUSTOM_PICK_PORT +#define GRPC_TEST_PICK_PORT +#endif + void grpc_test_init(int argc, char **argv); #ifdef __cplusplus diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 4c71831dec..dd294d9516 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -35,8 +35,8 @@ #include <memory> #include "test/core/util/test_config.h" -#include "test/cpp/util/echo_duplicate.pb.h" -#include "test/cpp/util/echo.pb.h" +#include "test/cpp/util/echo_duplicate.grpc.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" #include "src/cpp/util/time.h" #include <grpc++/async_unary_call.h> #include <grpc++/channel_arguments.h> @@ -532,15 +532,19 @@ TEST_F(AsyncEnd2endTest, MetadataRpc) { send_request.set_message("Hello"); std::pair<grpc::string, grpc::string> meta1("key1", "val1"); std::pair<grpc::string, grpc::string> meta2( - "key2-bin", {"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13}); + "key2-bin", + grpc::string("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", + 13)); std::pair<grpc::string, grpc::string> meta3("key3", "val3"); std::pair<grpc::string, grpc::string> meta6( "key4-bin", - {"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", 14}); + grpc::string("\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", + 14)); std::pair<grpc::string, grpc::string> meta5("key5", "val5"); std::pair<grpc::string, grpc::string> meta4( "key6-bin", - {"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15}); + grpc::string("\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", + 15)); cli_ctx.AddMetadata(meta1.first, meta1.second); cli_ctx.AddMetadata(meta2.first, meta2.second); @@ -595,6 +599,5 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); grpc_shutdown(); - google::protobuf::ShutdownProtobufLibrary(); return result; } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 41c2669533..f96051cafa 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -35,8 +35,8 @@ #include <thread> #include "test/core/util/test_config.h" -#include "test/cpp/util/echo_duplicate.pb.h" -#include "test/cpp/util/echo.pb.h" +#include "test/cpp/util/echo_duplicate.grpc.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" #include "src/cpp/util/time.h" #include "src/cpp/server/thread_pool.h" #include <grpc++/channel_arguments.h> @@ -83,10 +83,30 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request, class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { public: + TestServiceImpl() : signal_client_(false) {} + Status Echo(ServerContext* context, const EchoRequest* request, EchoResponse* response) GRPC_OVERRIDE { response->set_message(request->message()); MaybeEchoDeadline(context, request, response); + if (request->has_param() && request->param().client_cancel_after_us()) { + { + std::unique_lock<std::mutex> lock(mu_); + signal_client_ = true; + } + while (!context->IsCancelled()) { + std::this_thread::sleep_for(std::chrono::microseconds( + request->param().client_cancel_after_us())); + } + return Status::Cancelled; + } else if (request->has_param() && + request->param().server_cancel_after_us()) { + std::this_thread::sleep_for( + std::chrono::microseconds(request->param().server_cancel_after_us())); + return Status::Cancelled; + } else { + EXPECT_FALSE(context->IsCancelled()); + } return Status::OK; } @@ -130,6 +150,15 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { } return Status::OK; } + + bool signal_client() { + std::unique_lock<std::mutex> lock(mu_); + return signal_client_; + } + + private: + bool signal_client_; + std::mutex mu_; }; class TestServiceImplDupPkg @@ -151,7 +180,8 @@ class End2endTest : public ::testing::Test { server_address_ << "localhost:" << port; // Setup server ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), InsecureServerCredentials()); + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); builder.RegisterService(&service_); builder.RegisterService(&dup_pkg_service_); builder.SetThreadPool(&thread_pool_); @@ -423,6 +453,44 @@ TEST_F(End2endTest, BadCredentials) { EXPECT_EQ("Rpc sent on a lame channel.", s.details()); } +void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { + std::this_thread::sleep_for(std::chrono::microseconds(delay_us)); + while (!service->signal_client()) { + } + context->TryCancel(); +} + +// Client cancels rpc after 10ms +TEST_F(End2endTest, ClientCancelsRpc) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + const int kCancelDelayUs = 10 * 1000; + request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs); + + ClientContext context; + std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_); + Status s = stub_->Echo(&context, request, &response); + cancel_thread.join(); + EXPECT_EQ(StatusCode::CANCELLED, s.code()); + EXPECT_TRUE(s.details().empty()); +} + +// Server cancels rpc after 1ms +TEST_F(End2endTest, ServerCancelsRpc) { + ResetStub(); + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + request.mutable_param()->set_server_cancel_after_us(1000); + + ClientContext context; + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(StatusCode::CANCELLED, s.code()); + EXPECT_TRUE(s.details().empty()); +} + } // namespace testing } // namespace grpc @@ -432,6 +500,5 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); grpc_shutdown(); - google::protobuf::ShutdownProtobufLibrary(); return result; } diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc index 711f1b9540..eb6f5369a9 100644 --- a/test/cpp/end2end/generic_end2end_test.cc +++ b/test/cpp/end2end/generic_end2end_test.cc @@ -38,7 +38,7 @@ #include "src/cpp/util/time.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" -#include "test/cpp/util/echo.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" #include <grpc++/async_generic_service.h> #include <grpc++/async_unary_call.h> #include <grpc++/byte_buffer.h> @@ -47,6 +47,7 @@ #include <grpc++/client_context.h> #include <grpc++/create_channel.h> #include <grpc++/credentials.h> +#include <grpc++/generic_stub.h> #include <grpc++/server.h> #include <grpc++/server_builder.h> #include <grpc++/server_context.h> @@ -83,12 +84,21 @@ bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) { buffer->Dump(&slices); grpc::string buf; buf.reserve(buffer->Length()); - for (const Slice& s : slices) { - buf.append(reinterpret_cast<const char*>(s.begin()), s.size()); + for (auto s = slices.begin(); s != slices.end(); s++) { + buf.append(reinterpret_cast<const char*>(s->begin()), s->size()); } return message->ParseFromString(buf); } +std::unique_ptr<ByteBuffer> SerializeToByteBuffer( + grpc::protobuf::Message* message) { + grpc::string buf; + message->SerializeToString(&buf); + gpr_slice s = gpr_slice_from_copied_string(buf.c_str()); + Slice slice(s, Slice::STEAL_REF); + return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1)); +} + class GenericEnd2endTest : public ::testing::Test { protected: GenericEnd2endTest() : generic_service_("*") {} @@ -118,7 +128,7 @@ class GenericEnd2endTest : public ::testing::Test { void ResetStub() { std::shared_ptr<ChannelInterface> channel = CreateChannel( server_address_.str(), InsecureCredentials(), ChannelArguments()); - stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel)); + generic_stub_.reset(new GenericStub(channel)); } void server_ok(int i) { verify_ok(&srv_cq_, i, true); } @@ -127,6 +137,7 @@ class GenericEnd2endTest : public ::testing::Test { void client_fail(int i) { verify_ok(&cli_cq_, i, false); } void SendRpc(int num_rpcs) { + const grpc::string kMethodName("/grpc.cpp.test.util.TestService/Echo"); for (int i = 0; i < num_rpcs; i++) { EchoRequest send_request; EchoRequest recv_request; @@ -139,35 +150,42 @@ class GenericEnd2endTest : public ::testing::Test { GenericServerAsyncReaderWriter stream(&srv_ctx); send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader( - stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1))); + std::unique_ptr<GenericClientAsyncReaderWriter> call = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); client_ok(1); + std::unique_ptr<ByteBuffer> send_buffer = + SerializeToByteBuffer(&send_request); + call->Write(*send_buffer, tag(2)); + client_ok(2); + call->WritesDone(tag(3)); + client_ok(3); - generic_service_.RequestCall(&srv_ctx, &stream, &srv_cq_, tag(2)); + generic_service_.RequestCall(&srv_ctx, &stream, &srv_cq_, tag(4)); - verify_ok(generic_service_.completion_queue(), 2, true); + verify_ok(generic_service_.completion_queue(), 4, true); EXPECT_EQ(server_address_.str(), srv_ctx.host()); - EXPECT_EQ("/grpc.cpp.test.util.TestService/Echo", srv_ctx.method()); + EXPECT_EQ(kMethodName, srv_ctx.method()); ByteBuffer recv_buffer; - stream.Read(&recv_buffer, tag(3)); - server_ok(3); + stream.Read(&recv_buffer, tag(5)); + server_ok(5); EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); EXPECT_EQ(send_request.message(), recv_request.message()); send_response.set_message(recv_request.message()); - grpc::string buf; - send_response.SerializeToString(&buf); - gpr_slice s = gpr_slice_from_copied_string(buf.c_str()); - Slice slice(s, Slice::STEAL_REF); - ByteBuffer send_buffer(&slice, 1); - stream.Write(send_buffer, tag(4)); - server_ok(4); - - stream.Finish(Status::OK, tag(5)); - server_ok(5); + send_buffer = SerializeToByteBuffer(&send_response); + stream.Write(*send_buffer, tag(6)); + server_ok(6); + + stream.Finish(Status::OK, tag(7)); + server_ok(7); + + recv_buffer.Clear(); + call->Read(&recv_buffer, tag(8)); + client_ok(8); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); - response_reader->Finish(&recv_response, &recv_status, tag(4)); - client_ok(4); + call->Finish(&recv_status, tag(9)); + client_ok(9); EXPECT_EQ(send_response.message(), recv_response.message()); EXPECT_TRUE(recv_status.IsOk()); @@ -177,6 +195,7 @@ class GenericEnd2endTest : public ::testing::Test { CompletionQueue cli_cq_; CompletionQueue srv_cq_; std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_; + std::unique_ptr<grpc::GenericStub> generic_stub_; std::unique_ptr<Server> server_; AsyncGenericService generic_service_; std::ostringstream server_address_; @@ -196,6 +215,7 @@ TEST_F(GenericEnd2endTest, SequentialRpcs) { TEST_F(GenericEnd2endTest, SimpleBidiStreaming) { ResetStub(); + const grpc::string kMethodName("/grpc.cpp.test.util.TestService/BidiStream"); EchoRequest send_request; EchoRequest recv_request; EchoResponse send_response; @@ -206,17 +226,19 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) { GenericServerAsyncReaderWriter srv_stream(&srv_ctx); send_request.set_message("Hello"); - std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse> > - cli_stream(stub_->AsyncBidiStream(&cli_ctx, &cli_cq_, tag(1))); + std::unique_ptr<GenericClientAsyncReaderWriter> cli_stream = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); client_ok(1); generic_service_.RequestCall(&srv_ctx, &srv_stream, &srv_cq_, tag(2)); verify_ok(generic_service_.completion_queue(), 2, true); EXPECT_EQ(server_address_.str(), srv_ctx.host()); - EXPECT_EQ("/grpc.cpp.test.util.TestService/BidiStream", srv_ctx.method()); + EXPECT_EQ(kMethodName, srv_ctx.method()); - cli_stream->Write(send_request, tag(3)); + std::unique_ptr<ByteBuffer> send_buffer = + SerializeToByteBuffer(&send_request); + cli_stream->Write(*send_buffer, tag(3)); client_ok(3); ByteBuffer recv_buffer; @@ -226,22 +248,18 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) { EXPECT_EQ(send_request.message(), recv_request.message()); send_response.set_message(recv_request.message()); - grpc::string buf; - send_response.SerializeToString(&buf); - gpr_slice s = gpr_slice_from_copied_string(buf.c_str()); - Slice slice(s, Slice::STEAL_REF); - ByteBuffer send_buffer(&slice, 1); - srv_stream.Write(send_buffer, tag(5)); + send_buffer = SerializeToByteBuffer(&send_response); + srv_stream.Write(*send_buffer, tag(5)); server_ok(5); - cli_stream->Read(&recv_response, tag(6)); + cli_stream->Read(&recv_buffer, tag(6)); client_ok(6); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); EXPECT_EQ(send_response.message(), recv_response.message()); cli_stream->WritesDone(tag(7)); client_ok(7); - recv_buffer.Clear(); srv_stream.Read(&recv_buffer, tag(8)); server_fail(8); @@ -265,6 +283,5 @@ int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); int result = RUN_ALL_TESTS(); grpc_shutdown(); - google::protobuf::ShutdownProtobufLibrary(); return result; } diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index de6c6b7b77..7c5e1aa715 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -51,9 +51,9 @@ #include <grpc++/status.h> #include <grpc++/stream.h> #include "test/cpp/util/create_test_channel.h" -#include "test/cpp/interop/test.pb.h" -#include "test/cpp/interop/empty.pb.h" -#include "test/cpp/interop/messages.pb.h" +#include "test/cpp/interop/test.grpc.pb.h" +#include "test/cpp/interop/empty.grpc.pb.h" +#include "test/cpp/interop/messages.grpc.pb.h" DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google"); diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc index eceb600d4c..87bf48938b 100644 --- a/test/cpp/interop/server.cc +++ b/test/cpp/interop/server.cc @@ -49,9 +49,9 @@ #include <grpc++/server_credentials.h> #include <grpc++/status.h> #include <grpc++/stream.h> -#include "test/cpp/interop/test.pb.h" -#include "test/cpp/interop/empty.pb.h" -#include "test/cpp/interop/messages.pb.h" +#include "test/cpp/interop/test.grpc.pb.h" +#include "test/cpp/interop/empty.grpc.pb.h" +#include "test/cpp/interop/messages.grpc.pb.h" DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); DEFINE_int32(port, 0, "Server port."); @@ -213,8 +213,11 @@ void RunServer() { builder.RegisterService(&service); std::shared_ptr<ServerCredentials> creds = grpc::InsecureServerCredentials(); if (FLAGS_enable_ssl) { - SslServerCredentialsOptions ssl_opts = { - "", {{test_server1_key, test_server1_cert}}}; + 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); creds = grpc::SslServerCredentials(ssl_opts); } builder.AddListeningPort(server_address.str(), creds); diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 221fb30fc5..2dc5b3860f 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -36,7 +36,7 @@ #include "test/cpp/qps/histogram.h" #include "test/cpp/qps/timer.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include <condition_variable> #include <mutex> @@ -104,7 +104,7 @@ class Client { void EndThreads() { threads_.clear(); } - virtual void ThreadFunc(Histogram* histogram, size_t thread_idx) = 0; + virtual bool ThreadFunc(Histogram* histogram, size_t thread_idx) = 0; private: class Thread { @@ -113,20 +113,24 @@ class Client { : done_(false), new_(nullptr), impl_([this, idx, client]() { - for (;;) { - // run the loop body - client->ThreadFunc(&histogram_, idx); - // lock, see if we're done - std::lock_guard<std::mutex> g(mu_); - if (done_) return; - // also check if we're marking, and swap out the histogram if so - if (new_) { - new_->Swap(&histogram_); - new_ = nullptr; - cv_.notify_one(); + for (;;) { + // run the loop body + bool thread_still_ok = client->ThreadFunc(&histogram_, idx); + // lock, see if we're done + std::lock_guard<std::mutex> g(mu_); + if (!thread_still_ok) { + gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); + done_ = true; + } + if (done_) {return;} + // check if we're marking, swap out the histogram if so + if (new_) { + new_->Swap(&histogram_); + new_ = nullptr; + cv_.notify_one(); + } } - } - }) {} + }) {} ~Thread() { { @@ -164,8 +168,12 @@ class Client { std::unique_ptr<Timer> timer_; }; -std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& args); -std::unique_ptr<Client> CreateAsyncClient(const ClientConfig& args); +std::unique_ptr<Client> + CreateSynchronousUnaryClient(const ClientConfig& args); +std::unique_ptr<Client> + CreateSynchronousStreamingClient(const ClientConfig& args); +std::unique_ptr<Client> CreateAsyncUnaryClient(const ClientConfig& args); +std::unique_ptr<Client> CreateAsyncStreamingClient(const ClientConfig& args); } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index 526f37a1fd..0a6d9beeca 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -46,9 +46,9 @@ #include <grpc++/async_unary_call.h> #include <grpc++/client_context.h> #include <grpc++/status.h> -#include "test/core/util/grpc_profiler.h" +#include <grpc++/stream.h> #include "test/cpp/util/create_test_channel.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/timer.h" #include "test/cpp/qps/client.h" @@ -59,13 +59,13 @@ class ClientRpcContext { public: ClientRpcContext() {} virtual ~ClientRpcContext() {} - virtual bool RunNextState() = 0; // do next state, return false if steps done + // next state, return false if done. Collect stats when appropriate + virtual bool RunNextState(bool, Histogram* hist) = 0; virtual void StartNewClone() = 0; static void* tag(ClientRpcContext* c) { return reinterpret_cast<void*>(c); } static ClientRpcContext* detag(void* t) { return reinterpret_cast<ClientRpcContext*>(t); } - virtual void report_stats(Histogram* hist) = 0; }; template <class RequestType, class ResponseType> @@ -89,9 +89,12 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { response_reader_( start_req(stub_, &context_, req_, ClientRpcContext::tag(this))) {} ~ClientRpcContextUnaryImpl() GRPC_OVERRIDE {} - bool RunNextState() GRPC_OVERRIDE { return (this->*next_state_)(); } - void report_stats(Histogram* hist) GRPC_OVERRIDE { - hist->Add((Timer::Now() - start_) * 1e9); + bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE { + bool ret = (this->*next_state_)(ok); + if (!ret) { + hist->Add((Timer::Now() - start_) * 1e9); + } + return ret; } void StartNewClone() GRPC_OVERRIDE { @@ -99,16 +102,16 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { } private: - bool ReqSent() { + bool ReqSent(bool) { next_state_ = &ClientRpcContextUnaryImpl::RespDone; response_reader_->Finish(&response_, &status_, ClientRpcContext::tag(this)); return true; } - bool RespDone() { + bool RespDone(bool) { next_state_ = &ClientRpcContextUnaryImpl::DoCallBack; return false; } - bool DoCallBack() { + bool DoCallBack(bool) { callback_(status_, &response_); return false; } @@ -116,7 +119,7 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { TestService::Stub* stub_; RequestType req_; ResponseType response_; - bool (ClientRpcContextUnaryImpl::*next_state_)(); + bool (ClientRpcContextUnaryImpl::*next_state_)(bool); std::function<void(grpc::Status, ResponseType*)> callback_; std::function<std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>( TestService::Stub*, grpc::ClientContext*, const RequestType&, void*)> @@ -127,24 +130,19 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { response_reader_; }; -class AsyncClient GRPC_FINAL : public Client { +class AsyncUnaryClient GRPC_FINAL : public Client { public: - explicit AsyncClient(const ClientConfig& config) : Client(config) { + explicit AsyncUnaryClient(const ClientConfig& config) : Client(config) { for (int i = 0; i < config.async_client_threads(); i++) { cli_cqs_.emplace_back(new CompletionQueue); } - auto payload_size = config.payload_size(); - auto check_done = [payload_size](grpc::Status s, SimpleResponse* response) { - GPR_ASSERT(s.IsOk() && (response->payload().type() == - grpc::testing::PayloadType::COMPRESSABLE) && - (response->payload().body().length() == - static_cast<size_t>(payload_size))); - }; + auto check_done = [](grpc::Status s, SimpleResponse* response) {}; int t = 0; for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) { - for (auto& channel : channels_) { + for (auto channel = channels_.begin(); channel != channels_.end(); + channel++) { auto* cq = cli_cqs_[t].get(); t = (t + 1) % cli_cqs_.size(); auto start_req = [cq](TestService::Stub* stub, grpc::ClientContext* ctx, @@ -152,7 +150,7 @@ class AsyncClient GRPC_FINAL : public Client { return stub->AsyncUnaryCall(ctx, request, cq, tag); }; - TestService::Stub* stub = channel.get_stub(); + TestService::Stub* stub = channel->get_stub(); const SimpleRequest& request = request_; new ClientRpcContextUnaryImpl<SimpleRequest, SimpleResponse>( stub, request, start_req, check_done); @@ -162,39 +160,181 @@ class AsyncClient GRPC_FINAL : public Client { StartThreads(config.async_client_threads()); } - ~AsyncClient() GRPC_OVERRIDE { + ~AsyncUnaryClient() GRPC_OVERRIDE { EndThreads(); - for (auto& cq : cli_cqs_) { - cq->Shutdown(); + for (auto cq = cli_cqs_.begin(); cq != cli_cqs_.end(); cq++) { + (*cq)->Shutdown(); void* got_tag; bool ok; - while (cq->Next(&got_tag, &ok)) { + while ((*cq)->Next(&got_tag, &ok)) { delete ClientRpcContext::detag(got_tag); } } } - void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE { + bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE { void* got_tag; bool ok; - cli_cqs_[thread_idx]->Next(&got_tag, &ok); + switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) { + case CompletionQueue::SHUTDOWN: return false; + case CompletionQueue::TIMEOUT: return true; + case CompletionQueue::GOT_EVENT: break; + } ClientRpcContext* ctx = ClientRpcContext::detag(got_tag); - if (ctx->RunNextState() == false) { + if (ctx->RunNextState(ok, histogram) == false) { + // call the callback and then delete it + ctx->RunNextState(ok, histogram); + ctx->StartNewClone(); + delete ctx; + } + + return true; + } + + std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_; +}; + +template <class RequestType, class ResponseType> +class ClientRpcContextStreamingImpl : public ClientRpcContext { + public: + ClientRpcContextStreamingImpl( + TestService::Stub *stub, const RequestType &req, + std::function< + std::unique_ptr<grpc::ClientAsyncReaderWriter< + RequestType,ResponseType>>( + TestService::Stub *, grpc::ClientContext *, void *)> start_req, + std::function<void(grpc::Status, ResponseType *)> on_done) + : context_(), + stub_(stub), + req_(req), + response_(), + next_state_(&ClientRpcContextStreamingImpl::ReqSent), + callback_(on_done), + start_req_(start_req), + start_(Timer::Now()), + stream_(start_req_(stub_, &context_, ClientRpcContext::tag(this))) {} + ~ClientRpcContextStreamingImpl() GRPC_OVERRIDE {} + bool RunNextState(bool ok, Histogram *hist) GRPC_OVERRIDE { + return (this->*next_state_)(ok, hist); + } + void StartNewClone() GRPC_OVERRIDE { + new ClientRpcContextStreamingImpl(stub_, req_, start_req_, callback_); + } + + private: + bool ReqSent(bool ok, Histogram *) { + return StartWrite(ok); + } + bool StartWrite(bool ok) { + if (!ok) { + return(false); + } + start_ = Timer::Now(); + next_state_ = &ClientRpcContextStreamingImpl::WriteDone; + stream_->Write(req_, ClientRpcContext::tag(this)); + return true; + } + bool WriteDone(bool ok, Histogram *) { + if (!ok) { + return(false); + } + next_state_ = &ClientRpcContextStreamingImpl::ReadDone; + stream_->Read(&response_, ClientRpcContext::tag(this)); + return true; + } + bool ReadDone(bool ok, Histogram *hist) { + hist->Add((Timer::Now() - start_) * 1e9); + return StartWrite(ok); + } + grpc::ClientContext context_; + TestService::Stub *stub_; + RequestType req_; + ResponseType response_; + bool (ClientRpcContextStreamingImpl::*next_state_)(bool, Histogram *); + std::function<void(grpc::Status, ResponseType *)> callback_; + std::function<std::unique_ptr<grpc::ClientAsyncReaderWriter< + RequestType,ResponseType>>( + TestService::Stub *, grpc::ClientContext *, void *)> start_req_; + grpc::Status status_; + double start_; + std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType,ResponseType>> + stream_; +}; + +class AsyncStreamingClient GRPC_FINAL : public Client { + public: + explicit AsyncStreamingClient(const ClientConfig &config) : Client(config) { + for (int i = 0; i < config.async_client_threads(); i++) { + cli_cqs_.emplace_back(new CompletionQueue); + } + + auto check_done = [](grpc::Status s, SimpleResponse* response) {}; + + int t = 0; + for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) { + for (auto channel = channels_.begin(); channel != channels_.end(); + channel++) { + auto* cq = cli_cqs_[t].get(); + t = (t + 1) % cli_cqs_.size(); + auto start_req = [cq](TestService::Stub *stub, grpc::ClientContext *ctx, + void *tag) { + auto stream = stub->AsyncStreamingCall(ctx, cq, tag); + return stream; + }; + + TestService::Stub *stub = channel->get_stub(); + const SimpleRequest &request = request_; + new ClientRpcContextStreamingImpl<SimpleRequest, SimpleResponse>( + stub, request, start_req, check_done); + } + } + + StartThreads(config.async_client_threads()); + } + + ~AsyncStreamingClient() GRPC_OVERRIDE { + EndThreads(); + + for (auto cq = cli_cqs_.begin(); cq != cli_cqs_.end(); cq++) { + (*cq)->Shutdown(); + void *got_tag; + bool ok; + while ((*cq)->Next(&got_tag, &ok)) { + delete ClientRpcContext::detag(got_tag); + } + } + } + + bool ThreadFunc(Histogram *histogram, size_t thread_idx) GRPC_OVERRIDE { + void *got_tag; + bool ok; + switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) { + case CompletionQueue::SHUTDOWN: return false; + case CompletionQueue::TIMEOUT: return true; + case CompletionQueue::GOT_EVENT: break; + } + + ClientRpcContext *ctx = ClientRpcContext::detag(got_tag); + if (ctx->RunNextState(ok, histogram) == false) { // call the callback and then delete it - ctx->report_stats(histogram); - ctx->RunNextState(); + ctx->RunNextState(ok, histogram); ctx->StartNewClone(); delete ctx; } + + return true; } std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_; }; -std::unique_ptr<Client> CreateAsyncClient(const ClientConfig& args) { - return std::unique_ptr<Client>(new AsyncClient(args)); +std::unique_ptr<Client> CreateAsyncUnaryClient(const ClientConfig& args) { + return std::unique_ptr<Client>(new AsyncUnaryClient(args)); +} +std::unique_ptr<Client> CreateAsyncStreamingClient(const ClientConfig& args) { + return std::unique_ptr<Client>(new AsyncStreamingClient(args)); } } // namespace testing diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 7bb7231c6f..aea5a0fb27 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -48,45 +48,91 @@ #include <grpc/support/host_port.h> #include <gflags/gflags.h> #include <grpc++/client_context.h> -#include <grpc++/status.h> #include <grpc++/server.h> #include <grpc++/server_builder.h> -#include "test/core/util/grpc_profiler.h" +#include <grpc++/status.h> +#include <grpc++/stream.h> +#include <gtest/gtest.h> #include "test/cpp/util/create_test_channel.h" #include "test/cpp/qps/client.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/histogram.h" #include "test/cpp/qps/timer.h" namespace grpc { namespace testing { -class SynchronousClient GRPC_FINAL : public Client { +class SynchronousClient : public Client { public: SynchronousClient(const ClientConfig& config) : Client(config) { - size_t num_threads = - config.outstanding_rpcs_per_channel() * config.client_channels(); - responses_.resize(num_threads); - StartThreads(num_threads); + num_threads_ = + config.outstanding_rpcs_per_channel() * config.client_channels(); + responses_.resize(num_threads_); } - ~SynchronousClient() { EndThreads(); } + virtual ~SynchronousClient() { EndThreads(); } + + protected: + size_t num_threads_; + std::vector<SimpleResponse> responses_; +}; - void ThreadFunc(Histogram* histogram, size_t thread_idx) { +class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { + public: + SynchronousUnaryClient(const ClientConfig& config): + SynchronousClient(config) {StartThreads(num_threads_);} + ~SynchronousUnaryClient() {} + + bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE { auto* stub = channels_[thread_idx % channels_.size()].get_stub(); double start = Timer::Now(); grpc::ClientContext context; grpc::Status s = stub->UnaryCall(&context, request_, &responses_[thread_idx]); histogram->Add((Timer::Now() - start) * 1e9); + return s.IsOk(); } +}; - private: - std::vector<SimpleResponse> responses_; +class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { + public: + SynchronousStreamingClient(const ClientConfig& config): + SynchronousClient(config) { + for (size_t thread_idx=0;thread_idx<num_threads_;thread_idx++){ + auto* stub = channels_[thread_idx % channels_.size()].get_stub(); + stream_ = stub->StreamingCall(&context_); + } + StartThreads(num_threads_); + } + ~SynchronousStreamingClient() { + if (stream_) { + SimpleResponse response; + stream_->WritesDone(); + EXPECT_TRUE(stream_->Finish().IsOk()); + } + } + + bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE { + double start = Timer::Now(); + if (stream_->Write(request_) && stream_->Read(&responses_[thread_idx])) { + histogram->Add((Timer::Now() - start) * 1e9); + return true; + } + return false; + } + private: + grpc::ClientContext context_; + std::unique_ptr<grpc::ClientReaderWriter<SimpleRequest, + SimpleResponse>> stream_; }; -std::unique_ptr<Client> CreateSynchronousClient(const ClientConfig& config) { - return std::unique_ptr<Client>(new SynchronousClient(config)); +std::unique_ptr<Client> +CreateSynchronousUnaryClient(const ClientConfig& config) { + return std::unique_ptr<Client>(new SynchronousUnaryClient(config)); +} +std::unique_ptr<Client> +CreateSynchronousStreamingClient(const ClientConfig& config) { + return std::unique_ptr<Client>(new SynchronousStreamingClient(config)); } } // namespace testing diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index d29ca1de94..f44883783d 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -74,7 +74,9 @@ static vector<string> get_hosts(const string& name) { ScenarioResult RunScenario(const ClientConfig& initial_client_config, size_t num_clients, const ServerConfig& server_config, - size_t num_servers) { + size_t num_servers, + int warmup_seconds, + int benchmark_seconds) { // ClientContext allocator (all are destroyed at scope exit) list<ClientContext> contexts; auto alloc_context = [&contexts]() { @@ -146,7 +148,7 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, // Let everything warmup gpr_log(GPR_INFO, "Warming up"); gpr_timespec start = gpr_now(); - gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(5))); + gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(warmup_seconds))); // Start a run gpr_log(GPR_INFO, "Starting"); @@ -154,55 +156,55 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, server_mark.mutable_mark(); ClientArgs client_mark; client_mark.mutable_mark(); - for (auto& server : servers) { - GPR_ASSERT(server.stream->Write(server_mark)); + for (auto server = servers.begin(); server != servers.end(); server++) { + GPR_ASSERT(server->stream->Write(server_mark)); } - for (auto& client : clients) { - GPR_ASSERT(client.stream->Write(client_mark)); + for (auto client = clients.begin(); client != clients.end(); client++) { + GPR_ASSERT(client->stream->Write(client_mark)); } ServerStatus server_status; ClientStatus client_status; - for (auto& server : servers) { - GPR_ASSERT(server.stream->Read(&server_status)); + for (auto server = servers.begin(); server != servers.end(); server++) { + GPR_ASSERT(server->stream->Read(&server_status)); } - for (auto& client : clients) { - GPR_ASSERT(client.stream->Read(&client_status)); + for (auto client = clients.begin(); client != clients.end(); client++) { + GPR_ASSERT(client->stream->Read(&client_status)); } // Wait some time gpr_log(GPR_INFO, "Running"); - gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(15))); + gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(benchmark_seconds))); // Finish a run ScenarioResult result; gpr_log(GPR_INFO, "Finishing"); - for (auto& server : servers) { - GPR_ASSERT(server.stream->Write(server_mark)); + for (auto server = servers.begin(); server != servers.end(); server++) { + GPR_ASSERT(server->stream->Write(server_mark)); } - for (auto& client : clients) { - GPR_ASSERT(client.stream->Write(client_mark)); + for (auto client = clients.begin(); client != clients.end(); client++) { + GPR_ASSERT(client->stream->Write(client_mark)); } - for (auto& server : servers) { - GPR_ASSERT(server.stream->Read(&server_status)); + for (auto server = servers.begin(); server != servers.end(); server++) { + GPR_ASSERT(server->stream->Read(&server_status)); const auto& stats = server_status.stats(); result.server_resources.push_back(ResourceUsage{ stats.time_elapsed(), stats.time_user(), stats.time_system()}); } - for (auto& client : clients) { - GPR_ASSERT(client.stream->Read(&client_status)); + for (auto client = clients.begin(); client != clients.end(); client++) { + GPR_ASSERT(client->stream->Read(&client_status)); const auto& stats = client_status.stats(); result.latencies.MergeProto(stats.latencies()); result.client_resources.push_back(ResourceUsage{ stats.time_elapsed(), stats.time_user(), stats.time_system()}); } - for (auto& client : clients) { - GPR_ASSERT(client.stream->WritesDone()); - GPR_ASSERT(client.stream->Finish().IsOk()); + for (auto client = clients.begin(); client != clients.end(); client++) { + GPR_ASSERT(client->stream->WritesDone()); + GPR_ASSERT(client->stream->Finish().IsOk()); } - for (auto& server : servers) { - GPR_ASSERT(server.stream->WritesDone()); - GPR_ASSERT(server.stream->Finish().IsOk()); + for (auto server = servers.begin(); server != servers.end(); server++) { + GPR_ASSERT(server->stream->WritesDone()); + GPR_ASSERT(server->stream->Finish().IsOk()); } return result; } diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index d87e80dc55..b3a8bf8cc4 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -35,7 +35,7 @@ #define TEST_QPS_DRIVER_H #include "test/cpp/qps/histogram.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" namespace grpc { namespace testing { @@ -54,7 +54,10 @@ struct ScenarioResult { ScenarioResult RunScenario(const grpc::testing::ClientConfig& client_config, size_t num_clients, const grpc::testing::ServerConfig& server_config, - size_t num_servers); + size_t num_servers, + int warmup_seconds, + int benchmark_seconds); + } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h index 7ba00e94c3..0547b7283a 100644 --- a/test/cpp/qps/histogram.h +++ b/test/cpp/qps/histogram.h @@ -35,7 +35,7 @@ #define TEST_QPS_HISTOGRAM_H #include <grpc/support/histogram.h> -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" namespace grpc { namespace testing { @@ -50,10 +50,10 @@ class Histogram { void Merge(Histogram* h) { gpr_histogram_merge(impl_, h->impl_); } void Add(double value) { gpr_histogram_add(impl_, value); } - double Percentile(double pctile) { + double Percentile(double pctile) const { return gpr_histogram_percentile(impl_, pctile); } - double Count() { return gpr_histogram_count(impl_); } + double Count() const { return gpr_histogram_count(impl_); } void Swap(Histogram* other) { std::swap(impl_, other->impl_); } void FillProto(HistogramData* p) { size_t n; diff --git a/test/cpp/qps/qps-sweep.sh b/test/cpp/qps/qps-sweep.sh new file mode 100755 index 0000000000..7bc6eade2c --- /dev/null +++ b/test/cpp/qps/qps-sweep.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +if [ x"$QPS_WORKERS" == x ]; then + echo Error: Must set QPS_WORKERS variable in form \ + "host:port,host:port,..." 1>&2 + exit 1 +fi + +bins=`find . .. ../.. ../../.. -name bins | head -1` + +for channels in 1 2 4 8 +do + for client in SYNCHRONOUS_CLIENT ASYNC_CLIENT + do + for server in SYNCHRONOUS_SERVER ASYNC_SERVER + do + for rpc in UNARY STREAMING + do + echo "Test $rpc $client $server , $channels channels" + "$bins"/opt/qps_driver --rpc_type=$rpc \ + --client_type=$client --server_type=$server + done + done + done +done diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc index 5e9a577f8e..220f826118 100644 --- a/test/cpp/qps/qps_driver.cc +++ b/test/cpp/qps/qps_driver.cc @@ -35,13 +35,17 @@ #include <grpc/support/log.h> #include "test/cpp/qps/driver.h" -#include "test/cpp/qps/stats.h" +#include "test/cpp/qps/report.h" DEFINE_int32(num_clients, 1, "Number of client binaries"); DEFINE_int32(num_servers, 1, "Number of server binaries"); +DEFINE_int32(warmup_seconds, 5, "Warmup time (in seconds)"); +DEFINE_int32(benchmark_seconds, 30, "Benchmark time (in seconds)"); + // Common config DEFINE_bool(enable_ssl, false, "Use SSL"); +DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING"); // Server config DEFINE_int32(server_threads, 1, "Number of server threads"); @@ -59,8 +63,8 @@ using grpc::testing::ClientConfig; using grpc::testing::ServerConfig; using grpc::testing::ClientType; using grpc::testing::ServerType; +using grpc::testing::RpcType; using grpc::testing::ResourceUsage; -using grpc::testing::sum; // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. @@ -73,6 +77,9 @@ int main(int argc, char** argv) { grpc_init(); ParseCommandLineFlags(&argc, &argv, true); + RpcType rpc_type; + GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type)); + ClientType client_type; ServerType server_type; GPR_ASSERT(ClientType_Parse(FLAGS_client_type, &client_type)); @@ -86,46 +93,20 @@ int main(int argc, char** argv) { client_config.set_client_channels(FLAGS_client_channels); client_config.set_payload_size(FLAGS_payload_size); client_config.set_async_client_threads(FLAGS_async_client_threads); + client_config.set_rpc_type(rpc_type); ServerConfig server_config; server_config.set_server_type(server_type); server_config.set_threads(FLAGS_server_threads); server_config.set_enable_ssl(FLAGS_enable_ssl); - auto result = RunScenario(client_config, FLAGS_num_clients, server_config, - FLAGS_num_servers); - - gpr_log(GPR_INFO, "QPS: %.1f", - result.latencies.Count() / - average(result.client_resources, - [](ResourceUsage u) { return u.wall_time; })); - - gpr_log(GPR_INFO, "Latencies (50/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f us", - result.latencies.Percentile(50) / 1000, - result.latencies.Percentile(95) / 1000, - result.latencies.Percentile(99) / 1000, - result.latencies.Percentile(99.9) / 1000); - - gpr_log(GPR_INFO, "Server system time: %.2f%%", - 100.0 * sum(result.server_resources, - [](ResourceUsage u) { return u.system_time; }) / - sum(result.server_resources, - [](ResourceUsage u) { return u.wall_time; })); - gpr_log(GPR_INFO, "Server user time: %.2f%%", - 100.0 * sum(result.server_resources, - [](ResourceUsage u) { return u.user_time; }) / - sum(result.server_resources, - [](ResourceUsage u) { return u.wall_time; })); - gpr_log(GPR_INFO, "Client system time: %.2f%%", - 100.0 * sum(result.client_resources, - [](ResourceUsage u) { return u.system_time; }) / - sum(result.client_resources, - [](ResourceUsage u) { return u.wall_time; })); - gpr_log(GPR_INFO, "Client user time: %.2f%%", - 100.0 * sum(result.client_resources, - [](ResourceUsage u) { return u.user_time; }) / - sum(result.client_resources, - [](ResourceUsage u) { return u.wall_time; })); + auto result = RunScenario(client_config, FLAGS_num_clients, + server_config, FLAGS_num_servers, + FLAGS_warmup_seconds, FLAGS_benchmark_seconds); + + ReportQPSPerCore(result, server_config); + ReportLatency(result); + ReportTimes(result); grpc_shutdown(); return 0; diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto index 6a7170bf58..1553ef5f07 100644 --- a/test/cpp/qps/qpstest.proto +++ b/test/cpp/qps/qpstest.proto @@ -87,15 +87,21 @@ enum ServerType { ASYNC_SERVER = 2; } +enum RpcType { + UNARY = 1; + STREAMING = 2; +} + message ClientConfig { repeated string server_targets = 1; required ClientType client_type = 2; - required bool enable_ssl = 3; + optional bool enable_ssl = 3 [default=false]; required int32 outstanding_rpcs_per_channel = 4; required int32 client_channels = 5; required int32 payload_size = 6; // only for async client: optional int32 async_client_threads = 7; + optional RpcType rpc_type = 8 [default=UNARY]; } // Request current stats @@ -121,8 +127,8 @@ message ClientStatus { message ServerConfig { required ServerType server_type = 1; - required int32 threads = 2; - required bool enable_ssl = 3; + optional int32 threads = 2 [default=1]; + optional bool enable_ssl = 3 [default=false]; } message ServerArgs { @@ -144,7 +150,7 @@ message SimpleRequest { // Desired payload size in the response from the server. // If response_type is COMPRESSABLE, this denotes the size before compression. - optional int32 response_size = 2; + optional int32 response_size = 2 [default=0]; // Optional input payload sent along with the request. optional Payload payload = 3; @@ -154,72 +160,14 @@ message SimpleResponse { optional Payload payload = 1; } -message StreamingInputCallRequest { - // Optional input payload sent along with the request. - optional Payload payload = 1; - - // Not expecting any payload from the response. -} - -message StreamingInputCallResponse { - // Aggregated size of payloads received from the client. - optional int32 aggregated_payload_size = 1; -} - -message ResponseParameters { - // Desired payload sizes in responses from the server. - // If response_type is COMPRESSABLE, this denotes the size before compression. - required int32 size = 1; - - // Desired interval between consecutive responses in the response stream in - // microseconds. - required int32 interval_us = 2; -} - -message StreamingOutputCallRequest { - // Desired payload type in the response from the server. - // If response_type is RANDOM, the payload from each response in the stream - // might be of different types. This is to simulate a mixed type of payload - // stream. - optional PayloadType response_type = 1 [default=COMPRESSABLE]; - - repeated ResponseParameters response_parameters = 2; - - // Optional input payload sent along with the request. - optional Payload payload = 3; -} - -message StreamingOutputCallResponse { - optional Payload payload = 1; -} - service TestService { // One request followed by one response. // The server returns the client payload as-is. rpc UnaryCall(SimpleRequest) returns (SimpleResponse); - // One request followed by a sequence of responses (streamed download). - // The server returns the payload with client desired type and sizes. - rpc StreamingOutputCall(StreamingOutputCallRequest) - returns (stream StreamingOutputCallResponse); - - // A sequence of requests followed by one response (streamed upload). - // The server returns the aggregated size of client payload as the result. - rpc StreamingInputCall(stream StreamingInputCallRequest) - returns (StreamingInputCallResponse); - - // A sequence of requests with each request served by the server immediately. - // As one request could lead to multiple responses, this interface - // demonstrates the idea of full duplexing. - rpc FullDuplexCall(stream StreamingOutputCallRequest) - returns (stream StreamingOutputCallResponse); - - // A sequence of requests followed by a sequence of responses. - // The server buffers all the client requests and then serves them in order. A - // stream of responses are returned to the client when the server starts with - // first request. - rpc HalfDuplexCall(stream StreamingOutputCallRequest) - returns (stream StreamingOutputCallResponse); + // One request followed by one response. + // The server returns the client payload as-is. + rpc StreamingCall(stream SimpleRequest) returns (stream SimpleResponse); } service Worker { diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc new file mode 100644 index 0000000000..29d88da344 --- /dev/null +++ b/test/cpp/qps/report.cc @@ -0,0 +1,94 @@ +/* + * + * 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 "test/cpp/qps/report.h" + +#include <grpc/support/log.h> +#include "test/cpp/qps/stats.h" + +namespace grpc { +namespace testing { + +// QPS: XXX +void ReportQPS(const ScenarioResult& result) { + gpr_log(GPR_INFO, "QPS: %.1f", + result.latencies.Count() / + average(result.client_resources, + [](ResourceUsage u) { return u.wall_time; })); +} + +// QPS: XXX (YYY/server core) +void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& server_config) { + auto qps = + result.latencies.Count() / + average(result.client_resources, + [](ResourceUsage u) { return u.wall_time; }); + + gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps, qps/server_config.threads()); +} + +// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us +void ReportLatency(const ScenarioResult& result) { + gpr_log(GPR_INFO, "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us", + result.latencies.Percentile(50) / 1000, + result.latencies.Percentile(90) / 1000, + result.latencies.Percentile(95) / 1000, + result.latencies.Percentile(99) / 1000, + result.latencies.Percentile(99.9) / 1000); +} + +void ReportTimes(const ScenarioResult& result) { + gpr_log(GPR_INFO, "Server system time: %.2f%%", + 100.0 * sum(result.server_resources, + [](ResourceUsage u) { return u.system_time; }) / + sum(result.server_resources, + [](ResourceUsage u) { return u.wall_time; })); + gpr_log(GPR_INFO, "Server user time: %.2f%%", + 100.0 * sum(result.server_resources, + [](ResourceUsage u) { return u.user_time; }) / + sum(result.server_resources, + [](ResourceUsage u) { return u.wall_time; })); + gpr_log(GPR_INFO, "Client system time: %.2f%%", + 100.0 * sum(result.client_resources, + [](ResourceUsage u) { return u.system_time; }) / + sum(result.client_resources, + [](ResourceUsage u) { return u.wall_time; })); + gpr_log(GPR_INFO, "Client user time: %.2f%%", + 100.0 * sum(result.client_resources, + [](ResourceUsage u) { return u.user_time; }) / + sum(result.client_resources, + [](ResourceUsage u) { return u.wall_time; })); +} + +} // namespace testing +} // namespace grpc diff --git a/src/php/ext/grpc/completion_queue.h b/test/cpp/qps/report.h index 1d386cc58f..343e426ca4 100755..100644 --- a/src/php/ext/grpc/completion_queue.h +++ b/test/cpp/qps/report.h @@ -31,32 +31,27 @@ * */ -#ifndef NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_ -#define NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_ +#ifndef TEST_QPS_REPORT_H +#define TEST_QPS_REPORT_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_grpc.h" - -#include "grpc/grpc.h" +#include "test/cpp/qps/driver.h" -/* Class entry for the PHP CompletionQueue class */ -extern zend_class_entry *grpc_ce_completion_queue; +namespace grpc { +namespace testing { -/* Wrapper class for grpc_completion_queue that can be associated with a - PHP object */ -typedef struct wrapped_grpc_completion_queue { - zend_object std; +// QPS: XXX +void ReportQPS(const ScenarioResult& result); +// QPS: XXX (YYY/server core) +void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config); +// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us +void ReportLatency(const ScenarioResult& result); +// Server system time: XX% +// Server user time: XX% +// Client system time: XX% +// Client user time: XX% +void ReportTimes(const ScenarioResult& result); - grpc_completion_queue *wrapped; -} wrapped_grpc_completion_queue; +} // namespace testing +} // namespace grpc -/* Initialize the CompletionQueue class */ -void grpc_init_completion_queue(TSRMLS_D); - -#endif /* NET_GRPC_PHP_GRPC_COMPLETION_QUEUE_H_ */ +#endif diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc deleted file mode 100644 index e1907b069b..0000000000 --- a/test/cpp/qps/server.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <sys/time.h> -#include <sys/resource.h> -#include <sys/signal.h> -#include <thread> - -#include <unistd.h> - -#include <gflags/gflags.h> -#include <grpc/support/alloc.h> -#include <grpc/support/host_port.h> -#include <grpc++/config.h> -#include <grpc++/server.h> -#include <grpc++/server_builder.h> -#include <grpc++/server_context.h> -#include <grpc++/server_credentials.h> -#include <grpc++/status.h> -#include "src/cpp/server/thread_pool.h" -#include "test/core/util/grpc_profiler.h" -#include "test/cpp/qps/qpstest.pb.h" - -#include <grpc/grpc.h> -#include <grpc/support/log.h> - -DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); -DEFINE_int32(port, 0, "Server port."); -DEFINE_int32(server_threads, 4, "Number of server threads."); - -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::ThreadPool; -using grpc::testing::Payload; -using grpc::testing::PayloadType; -using grpc::testing::ServerStats; -using grpc::testing::SimpleRequest; -using grpc::testing::SimpleResponse; -using grpc::testing::StatsRequest; -using grpc::testing::TestService; -using grpc::Status; - -// In some distros, gflags is in the namespace google, and in some others, -// in gflags. This hack is enabling us to find both. -namespace google {} -namespace gflags {} -using namespace google; -using namespace gflags; - -static bool got_sigint = false; - -static void sigint_handler(int x) { got_sigint = 1; } - -static double time_double(struct timeval* tv) { - return tv->tv_sec + 1e-6 * tv->tv_usec; -} - -static bool SetPayload(PayloadType type, int size, Payload* payload) { - PayloadType response_type = type; - // TODO(yangg): Support UNCOMPRESSABLE payload. - if (type != PayloadType::COMPRESSABLE) { - return false; - } - payload->set_type(response_type); - std::unique_ptr<char[]> body(new char[size]()); - payload->set_body(body.get(), size); - return true; -} - -namespace { - -class TestServiceImpl GRPC_FINAL : public TestService::Service { - public: - Status CollectServerStats(ServerContext* context, const StatsRequest*, - ServerStats* response) { - struct rusage usage; - struct timeval tv; - gettimeofday(&tv, NULL); - getrusage(RUSAGE_SELF, &usage); - response->set_time_now(time_double(&tv)); - response->set_time_user(time_double(&usage.ru_utime)); - response->set_time_system(time_double(&usage.ru_stime)); - return Status::OK; - } - Status UnaryCall(ServerContext* context, const SimpleRequest* request, - SimpleResponse* response) { - if (request->has_response_size() && request->response_size() > 0) { - if (!SetPayload(request->response_type(), request->response_size(), - response->mutable_payload())) { - return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); - } - } - return Status::OK; - } -}; - -} // namespace - -static void RunServer() { - char* server_address = NULL; - gpr_join_host_port(&server_address, "::", FLAGS_port); - - TestServiceImpl service; - - SimpleRequest request; - SimpleResponse response; - - ServerBuilder builder; - builder.AddListeningPort(server_address, grpc::InsecureServerCredentials()); - builder.RegisterService(&service); - - std::unique_ptr<ThreadPool> pool(new ThreadPool(FLAGS_server_threads)); - builder.SetThreadPool(pool.get()); - - std::unique_ptr<Server> server(builder.BuildAndStart()); - gpr_log(GPR_INFO, "Server listening on %s\n", server_address); - - grpc_profiler_start("qps_server.prof"); - - while (!got_sigint) { - sleep(5); - } - - grpc_profiler_stop(); - - gpr_free(server_address); -} - -int main(int argc, char** argv) { - grpc_init(); - ParseCommandLineFlags(&argc, &argv, true); - - signal(SIGINT, sigint_handler); - - GPR_ASSERT(FLAGS_port != 0); - GPR_ASSERT(!FLAGS_enable_ssl); - RunServer(); - - grpc_shutdown(); - return 0; -} diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index ef71cb94d0..68e0115410 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -35,7 +35,7 @@ #define TEST_QPS_SERVER_H #include "test/cpp/qps/timer.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" namespace grpc { namespace testing { diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 586b6e7abe..b19c443c82 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -33,6 +33,7 @@ #include <forward_list> #include <functional> +#include <mutex> #include <sys/time.h> #include <sys/resource.h> #include <sys/signal.h> @@ -48,10 +49,10 @@ #include <grpc++/server_context.h> #include <grpc++/server_credentials.h> #include <grpc++/status.h> +#include <grpc++/stream.h> #include <gtest/gtest.h> #include "src/cpp/server/thread_pool.h" -#include "test/core/util/grpc_profiler.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/server.h" #include <grpc/grpc.h> @@ -63,7 +64,8 @@ namespace testing { class AsyncQpsServerTest : public Server { public: AsyncQpsServerTest(const ServerConfig& config, int port) - : srv_cq_(), async_service_(&srv_cq_), server_(nullptr) { + : srv_cq_(), async_service_(&srv_cq_), server_(nullptr), + shutdown_(false) { char* server_address = NULL; gpr_join_host_port(&server_address, "::", port); @@ -78,10 +80,16 @@ class AsyncQpsServerTest : public Server { using namespace std::placeholders; request_unary_ = std::bind(&TestService::AsyncService::RequestUnaryCall, &async_service_, _1, _2, _3, &srv_cq_, _4); + request_streaming_ = + std::bind(&TestService::AsyncService::RequestStreamingCall, + &async_service_, _1, _2, &srv_cq_, _3); for (int i = 0; i < 100; i++) { contexts_.push_front( new ServerRpcContextUnaryImpl<SimpleRequest, SimpleResponse>( - request_unary_, UnaryCall)); + request_unary_, ProcessRPC)); + contexts_.push_front( + new ServerRpcContextStreamingImpl<SimpleRequest, SimpleResponse>( + request_streaming_, ProcessRPC)); } for (int i = 0; i < config.threads(); i++) { threads_.push_back(std::thread([=]() { @@ -89,11 +97,12 @@ class AsyncQpsServerTest : public Server { bool ok; void* got_tag; while (srv_cq_.Next(&got_tag, &ok)) { - if (ok) { - ServerRpcContext* ctx = detag(got_tag); - // The tag is a pointer to an RPC context to invoke - if (ctx->RunNextState() == false) { - // this RPC context is done, so refresh it + ServerRpcContext* ctx = detag(got_tag); + // The tag is a pointer to an RPC context to invoke + if (ctx->RunNextState(ok) == false) { + // this RPC context is done, so refresh it + std::lock_guard<std::mutex> g(shutdown_mutex_); + if (!shutdown_) { ctx->Reset(); } } @@ -104,9 +113,13 @@ class AsyncQpsServerTest : public Server { } ~AsyncQpsServerTest() { server_->Shutdown(); - srv_cq_.Shutdown(); - for (auto& thr : threads_) { - thr.join(); + { + std::lock_guard<std::mutex> g(shutdown_mutex_); + shutdown_ = true; + srv_cq_.Shutdown(); + } + for (auto thr = threads_.begin(); thr != threads_.end(); thr++) { + thr->join(); } while (!contexts_.empty()) { delete contexts_.front(); @@ -119,7 +132,7 @@ class AsyncQpsServerTest : public Server { public: ServerRpcContext() {} virtual ~ServerRpcContext(){}; - virtual bool RunNextState() = 0; // do next state, return false if all done + virtual bool RunNextState(bool) = 0; // next state, return false if done virtual void Reset() = 0; // start this back at a clean state }; static void* tag(ServerRpcContext* func) { @@ -130,7 +143,7 @@ class AsyncQpsServerTest : public Server { } template <class RequestType, class ResponseType> - class ServerRpcContextUnaryImpl : public ServerRpcContext { + class ServerRpcContextUnaryImpl GRPC_FINAL : public ServerRpcContext { public: ServerRpcContextUnaryImpl( std::function<void(ServerContext*, RequestType*, @@ -146,7 +159,7 @@ class AsyncQpsServerTest : public Server { AsyncQpsServerTest::tag(this)); } ~ServerRpcContextUnaryImpl() GRPC_OVERRIDE {} - bool RunNextState() GRPC_OVERRIDE { return (this->*next_state_)(); } + bool RunNextState(bool ok) GRPC_OVERRIDE {return (this->*next_state_)(ok);} void Reset() GRPC_OVERRIDE { srv_ctx_ = ServerContext(); req_ = RequestType(); @@ -160,8 +173,12 @@ class AsyncQpsServerTest : public Server { } private: - bool finisher() { return false; } - bool invoker() { + bool finisher(bool) { return false; } + bool invoker(bool ok) { + if (!ok) { + return false; + } + ResponseType response; // Call the RPC processing function @@ -174,7 +191,7 @@ class AsyncQpsServerTest : public Server { } ServerContext srv_ctx_; RequestType req_; - bool (ServerRpcContextUnaryImpl::*next_state_)(); + bool (ServerRpcContextUnaryImpl::*next_state_)(bool); std::function<void(ServerContext*, RequestType*, grpc::ServerAsyncResponseWriter<ResponseType>*, void*)> request_method_; @@ -183,9 +200,89 @@ class AsyncQpsServerTest : public Server { grpc::ServerAsyncResponseWriter<ResponseType> response_writer_; }; - static Status UnaryCall(const SimpleRequest* request, - SimpleResponse* response) { - if (request->has_response_size() && request->response_size() > 0) { + template <class RequestType, class ResponseType> + class ServerRpcContextStreamingImpl GRPC_FINAL : public ServerRpcContext { + public: + ServerRpcContextStreamingImpl( + std::function<void(ServerContext *, + grpc::ServerAsyncReaderWriter<ResponseType, + RequestType> *, void *)> request_method, + std::function<grpc::Status(const RequestType *, ResponseType *)> + invoke_method) + : next_state_(&ServerRpcContextStreamingImpl::request_done), + request_method_(request_method), + invoke_method_(invoke_method), + stream_(&srv_ctx_) { + request_method_(&srv_ctx_, &stream_, AsyncQpsServerTest::tag(this)); + } + ~ServerRpcContextStreamingImpl() GRPC_OVERRIDE { + } + bool RunNextState(bool ok) GRPC_OVERRIDE {return (this->*next_state_)(ok);} + void Reset() GRPC_OVERRIDE { + srv_ctx_ = ServerContext(); + req_ = RequestType(); + stream_ = grpc::ServerAsyncReaderWriter<ResponseType, + RequestType>(&srv_ctx_); + + // Then request the method + next_state_ = &ServerRpcContextStreamingImpl::request_done; + request_method_(&srv_ctx_, &stream_, AsyncQpsServerTest::tag(this)); + } + + private: + bool request_done(bool ok) { + if (!ok) { + return false; + } + stream_.Read(&req_, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::read_done; + return true; + } + + bool read_done(bool ok) { + if (ok) { + // invoke the method + ResponseType response; + // Call the RPC processing function + grpc::Status status = invoke_method_(&req_, &response); + // initiate the write + stream_.Write(response, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::write_done; + } else { // client has sent writes done + // finish the stream + stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::finish_done; + } + return true; + } + bool write_done(bool ok) { + // now go back and get another streaming read! + if (ok) { + stream_.Read(&req_, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::read_done; + } + else { + stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::finish_done; + } + return true; + } + bool finish_done(bool ok) {return false; /* reset the context */ } + + ServerContext srv_ctx_; + RequestType req_; + bool (ServerRpcContextStreamingImpl::*next_state_)(bool); + std::function<void(ServerContext *, + grpc::ServerAsyncReaderWriter<ResponseType, + RequestType> *, void *)> request_method_; + std::function<grpc::Status(const RequestType *, ResponseType *)> + invoke_method_; + grpc::ServerAsyncReaderWriter<ResponseType,RequestType> stream_; + }; + + static Status ProcessRPC(const SimpleRequest* request, + SimpleResponse* response) { + if (request->response_size() > 0) { if (!SetPayload(request->response_type(), request->response_size(), response->mutable_payload())) { return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); @@ -200,7 +297,13 @@ class AsyncQpsServerTest : public Server { std::function<void(ServerContext*, SimpleRequest*, grpc::ServerAsyncResponseWriter<SimpleResponse>*, void*)> request_unary_; + std::function<void(ServerContext*, grpc::ServerAsyncReaderWriter< + SimpleResponse,SimpleRequest>*, void*)> + request_streaming_; std::forward_list<ServerRpcContext*> contexts_; + + std::mutex shutdown_mutex_; + bool shutdown_; }; std::unique_ptr<Server> CreateAsyncServer(const ServerConfig& config, diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 3e15fb61c0..2770233a7c 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -47,8 +47,7 @@ #include <grpc++/status.h> #include <grpc++/stream.h> #include "src/cpp/server/thread_pool.h" -#include "test/core/util/grpc_profiler.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/server.h" #include "test/cpp/qps/timer.h" @@ -62,7 +61,7 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service { public: Status UnaryCall(ServerContext* context, const SimpleRequest* request, SimpleResponse* response) GRPC_OVERRIDE { - if (request->has_response_size() && request->response_size() > 0) { + if (request->response_size() > 0) { if (!Server::SetPayload(request->response_type(), request->response_size(), response->mutable_payload())) { @@ -71,6 +70,23 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service { } return Status::OK; } + Status StreamingCall(ServerContext *context, + ServerReaderWriter<SimpleResponse, SimpleRequest>* + stream) GRPC_OVERRIDE { + SimpleRequest request; + while (stream->Read(&request)) { + SimpleResponse response; + if (request.response_size() > 0) { + if (!Server::SetPayload(request.response_type(), + request.response_size(), + response.mutable_payload())) { + return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); + } + } + stream->Write(response); + } + return Status::OK; + } }; class SynchronousServer GRPC_FINAL : public grpc::testing::Server { diff --git a/test/cpp/qps/smoke_test.cc b/test/cpp/qps/smoke_test.cc new file mode 100644 index 0000000000..c9d321f133 --- /dev/null +++ b/test/cpp/qps/smoke_test.cc @@ -0,0 +1,149 @@ +/* + * + * 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/support/log.h> + +#include "test/cpp/qps/driver.h" +#include "test/cpp/qps/report.h" + +namespace grpc { +namespace testing { + +static const int WARMUP = 5; +static const int BENCHMARK = 10; + +static void RunSynchronousUnaryPingPong() { + gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong"); + + ClientConfig client_config; + client_config.set_client_type(SYNCHRONOUS_CLIENT); + client_config.set_enable_ssl(false); + client_config.set_outstanding_rpcs_per_channel(1); + client_config.set_client_channels(1); + client_config.set_payload_size(1); + client_config.set_rpc_type(UNARY); + + ServerConfig server_config; + server_config.set_server_type(SYNCHRONOUS_SERVER); + server_config.set_enable_ssl(false); + server_config.set_threads(1); + + auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); + + ReportQPS(result); + ReportLatency(result); +} + +static void RunSynchronousStreamingPingPong() { + gpr_log(GPR_INFO, "Running Synchronous Streaming Ping Pong"); + + ClientConfig client_config; + client_config.set_client_type(SYNCHRONOUS_CLIENT); + client_config.set_enable_ssl(false); + client_config.set_outstanding_rpcs_per_channel(1); + client_config.set_client_channels(1); + client_config.set_payload_size(1); + client_config.set_rpc_type(STREAMING); + + ServerConfig server_config; + server_config.set_server_type(SYNCHRONOUS_SERVER); + server_config.set_enable_ssl(false); + server_config.set_threads(1); + + auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); + + ReportQPS(result); + ReportLatency(result); +} + +static void RunAsyncUnaryPingPong() { + gpr_log(GPR_INFO, "Running Async Unary Ping Pong"); + + ClientConfig client_config; + client_config.set_client_type(ASYNC_CLIENT); + client_config.set_enable_ssl(false); + client_config.set_outstanding_rpcs_per_channel(1); + client_config.set_client_channels(1); + client_config.set_payload_size(1); + client_config.set_async_client_threads(1); + client_config.set_rpc_type(UNARY); + + ServerConfig server_config; + server_config.set_server_type(ASYNC_SERVER); + server_config.set_enable_ssl(false); + server_config.set_threads(1); + + auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); + + ReportQPS(result); + ReportLatency(result); +} + +static void RunQPS() { + gpr_log(GPR_INFO, "Running QPS test"); + + ClientConfig client_config; + client_config.set_client_type(ASYNC_CLIENT); + client_config.set_enable_ssl(false); + client_config.set_outstanding_rpcs_per_channel(1000); + client_config.set_client_channels(8); + client_config.set_payload_size(1); + client_config.set_async_client_threads(8); + client_config.set_rpc_type(UNARY); + + ServerConfig server_config; + server_config.set_server_type(ASYNC_SERVER); + server_config.set_enable_ssl(false); + server_config.set_threads(4); + + auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK); + + ReportQPSPerCore(result, server_config); + ReportLatency(result); +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_init(); + + using namespace grpc::testing; + RunSynchronousStreamingPingPong(); + RunSynchronousUnaryPingPong(); + RunAsyncUnaryPingPong(); + RunQPS(); + + grpc_shutdown(); + return 0; +} diff --git a/test/cpp/qps/smoke_test.sh b/test/cpp/qps/smoke_test.sh new file mode 100755 index 0000000000..ba7f0a4f27 --- /dev/null +++ b/test/cpp/qps/smoke_test.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +# performs a single qps run with one client and one server + +set -ex + +cd $(dirname $0)/../../.. + +killall qps_worker || true + +config=opt + +NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'` + +make CONFIG=$config qps_worker qps_smoke_test -j$NUMCPUS + +bins/$config/qps_worker -driver_port 10000 -server_port 10001 & +PID1=$! +bins/$config/qps_worker -driver_port 10010 -server_port 10011 & +PID2=$! + +export QPS_WORKERS="localhost:10000,localhost:10010" + +bins/$config/qps_smoke_test $* + +kill -2 $PID1 $PID2 +wait + diff --git a/test/cpp/qps/stats.h b/test/cpp/qps/stats.h index ca59390ad7..82dc03e3da 100644 --- a/test/cpp/qps/stats.h +++ b/test/cpp/qps/stats.h @@ -43,8 +43,8 @@ namespace testing { template <class T, class F> double sum(const T& container, F functor) { double r = 0; - for (auto v : container) { - r += functor(v); + for (auto v = container.begin(); v != container.end(); v++) { + r += functor(*v); } return r; } diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc index 3c1342041c..d1b6bc1e55 100644 --- a/test/cpp/qps/timer.cc +++ b/test/cpp/qps/timer.cc @@ -36,6 +36,7 @@ #include <sys/time.h> #include <sys/resource.h> #include <grpc/support/time.h> +#include <grpc++/config.h> Timer::Timer() : start_(Sample()) {} diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc index fdcd9d5069..101eb9f969 100644 --- a/test/cpp/qps/worker.cc +++ b/test/cpp/qps/worker.cc @@ -55,7 +55,7 @@ #include <grpc++/stream.h> #include "test/core/util/grpc_profiler.h" #include "test/cpp/util/create_test_channel.h" -#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" #include "test/cpp/qps/client.h" #include "test/cpp/qps/server.h" @@ -71,15 +71,20 @@ using namespace gflags; static bool got_sigint = false; +static void sigint_handler(int x) {got_sigint = true;} + namespace grpc { namespace testing { std::unique_ptr<Client> CreateClient(const ClientConfig& config) { switch (config.client_type()) { case ClientType::SYNCHRONOUS_CLIENT: - return CreateSynchronousClient(config); + return (config.rpc_type() == RpcType::UNARY) ? + CreateSynchronousUnaryClient(config) : + CreateSynchronousStreamingClient(config); case ClientType::ASYNC_CLIENT: - return CreateAsyncClient(config); + return (config.rpc_type() == RpcType::UNARY) ? + CreateAsyncUnaryClient(config) : CreateAsyncStreamingClient(config); } abort(); } @@ -106,6 +111,60 @@ class WorkerImpl GRPC_FINAL : public Worker::Service { return Status(RESOURCE_EXHAUSTED); } + grpc_profiler_start("qps_client.prof"); + Status ret = RunTestBody(ctx,stream); + grpc_profiler_stop(); + return ret; + } + + Status RunServer(ServerContext* ctx, + ServerReaderWriter<ServerStatus, ServerArgs>* stream) + GRPC_OVERRIDE { + InstanceGuard g(this); + if (!g.Acquired()) { + return Status(RESOURCE_EXHAUSTED); + } + + grpc_profiler_start("qps_server.prof"); + Status ret = RunServerBody(ctx,stream); + grpc_profiler_stop(); + return ret; + } + + private: + // Protect against multiple clients using this worker at once. + class InstanceGuard { + public: + InstanceGuard(WorkerImpl* impl) + : impl_(impl), acquired_(impl->TryAcquireInstance()) {} + ~InstanceGuard() { + if (acquired_) { + impl_->ReleaseInstance(); + } + } + + bool Acquired() const { return acquired_; } + + private: + WorkerImpl* const impl_; + const bool acquired_; + }; + + bool TryAcquireInstance() { + std::lock_guard<std::mutex> g(mu_); + if (acquired_) return false; + acquired_ = true; + return true; + } + + void ReleaseInstance() { + std::lock_guard<std::mutex> g(mu_); + GPR_ASSERT(acquired_); + acquired_ = false; + } + + Status RunTestBody(ServerContext* ctx, + ServerReaderWriter<ClientStatus, ClientArgs>* stream) { ClientArgs args; if (!stream->Read(&args)) { return Status(INVALID_ARGUMENT); @@ -132,14 +191,8 @@ class WorkerImpl GRPC_FINAL : public Worker::Service { return Status::OK; } - Status RunServer(ServerContext* ctx, - ServerReaderWriter<ServerStatus, ServerArgs>* stream) - GRPC_OVERRIDE { - InstanceGuard g(this); - if (!g.Acquired()) { - return Status(RESOURCE_EXHAUSTED); - } - + Status RunServerBody(ServerContext* ctx, + ServerReaderWriter<ServerStatus, ServerArgs>* stream) { ServerArgs args; if (!stream->Read(&args)) { return Status(INVALID_ARGUMENT); @@ -167,38 +220,6 @@ class WorkerImpl GRPC_FINAL : public Worker::Service { return Status::OK; } - private: - // Protect against multiple clients using this worker at once. - class InstanceGuard { - public: - InstanceGuard(WorkerImpl* impl) - : impl_(impl), acquired_(impl->TryAcquireInstance()) {} - ~InstanceGuard() { - if (acquired_) { - impl_->ReleaseInstance(); - } - } - - bool Acquired() const { return acquired_; } - - private: - WorkerImpl* const impl_; - const bool acquired_; - }; - - bool TryAcquireInstance() { - std::lock_guard<std::mutex> g(mu_); - if (acquired_) return false; - acquired_ = true; - return true; - } - - void ReleaseInstance() { - std::lock_guard<std::mutex> g(mu_); - GPR_ASSERT(acquired_); - acquired_ = false; - } - std::mutex mu_; bool acquired_; }; @@ -229,6 +250,8 @@ int main(int argc, char** argv) { grpc_init(); ParseCommandLineFlags(&argc, &argv, true); + signal(SIGINT, sigint_handler); + grpc::testing::RunServer(); grpc_shutdown(); diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc new file mode 100644 index 0000000000..eb67b8d314 --- /dev/null +++ b/test/cpp/util/cli_call.cc @@ -0,0 +1,106 @@ +/* + * + * 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 "test/cpp/util/cli_call.h" + +#include <iostream> + +#include <grpc++/byte_buffer.h> +#include <grpc++/channel_interface.h> +#include <grpc++/client_context.h> +#include <grpc++/generic_stub.h> +#include <grpc++/status.h> +#include <grpc++/stream.h> + +#include <grpc/grpc.h> +#include <grpc/support/log.h> +#include <grpc/support/slice.h> + +namespace grpc { +namespace testing { +namespace { +void* tag(int i) { return (void*)(gpr_intptr) i; } +} // namespace + +void CliCall::Call(std::shared_ptr<grpc::ChannelInterface> channel, + const grpc::string& method, const grpc::string& request, + grpc::string* response) { + std::unique_ptr<grpc::GenericStub> stub(new grpc::GenericStub(channel)); + grpc::ClientContext ctx; + grpc::CompletionQueue cq; + std::unique_ptr<grpc::GenericClientAsyncReaderWriter> call( + stub->Call(&ctx, method, &cq, tag(1))); + void* got_tag; + bool ok; + cq.Next(&got_tag, &ok); + GPR_ASSERT(ok); + + gpr_slice s = gpr_slice_from_copied_string(request.c_str()); + grpc::Slice req_slice(s, grpc::Slice::STEAL_REF); + grpc::ByteBuffer send_buffer(&req_slice, 1); + call->Write(send_buffer, tag(2)); + cq.Next(&got_tag, &ok); + GPR_ASSERT(ok); + call->WritesDone(tag(3)); + cq.Next(&got_tag, &ok); + GPR_ASSERT(ok); + grpc::ByteBuffer recv_buffer; + call->Read(&recv_buffer, tag(4)); + cq.Next(&got_tag, &ok); + if (!ok) { + std::cout << "Failed to read response." << std::endl; + return; + } + grpc::Status status; + call->Finish(&status, tag(5)); + cq.Next(&got_tag, &ok); + GPR_ASSERT(ok); + + if (status.IsOk()) { + std::cout << "RPC finished with OK status." << std::endl; + std::vector<grpc::Slice> slices; + recv_buffer.Dump(&slices); + + response->clear(); + for (size_t i = 0; i < slices.size(); i++) { + response->append(reinterpret_cast<const char*>(slices[i].begin()), + slices[i].size()); + } + } else { + std::cout << "RPC finished with status code " << status.code() + << " details: " << status.details() << std::endl; + } +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/cli_call.h b/test/cpp/util/cli_call.h new file mode 100644 index 0000000000..7be8bb63c4 --- /dev/null +++ b/test/cpp/util/cli_call.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CLI_CALL_H +#define GRPC_TEST_CPP_UTIL_CLI_CALL_H + +#include <grpc++/channel_interface.h> +#include <grpc++/config.h> + +namespace grpc { +namespace testing { + +class CliCall GRPC_FINAL { + public: + static void Call(std::shared_ptr<grpc::ChannelInterface> channel, + const grpc::string& method, const grpc::string& request, + grpc::string* response); +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CLI_CALL_H diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc new file mode 100644 index 0000000000..32ef392cc4 --- /dev/null +++ b/test/cpp/util/cli_call_test.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 "test/core/util/test_config.h" +#include "test/cpp/util/cli_call.h" +#include "test/cpp/util/echo.grpc.pb.h" +#include "src/cpp/server/thread_pool.h" +#include <grpc++/channel_arguments.h> +#include <grpc++/channel_interface.h> +#include <grpc++/client_context.h> +#include <grpc++/create_channel.h> +#include <grpc++/credentials.h> +#include <grpc++/server.h> +#include <grpc++/server_builder.h> +#include <grpc++/server_context.h> +#include <grpc++/server_credentials.h> +#include <grpc++/status.h> +#include "test/core/util/port.h" +#include <gtest/gtest.h> + +#include <grpc/grpc.h> + +using grpc::cpp::test::util::EchoRequest; +using grpc::cpp::test::util::EchoResponse; + +namespace grpc { +namespace testing { + +class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { + public: + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) GRPC_OVERRIDE { + response->set_message(request->message()); + return Status::OK; + } +}; + +class CliCallTest : public ::testing::Test { + protected: + CliCallTest() : thread_pool_(2) {} + + void SetUp() GRPC_OVERRIDE { + int port = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << port; + // Setup server + ServerBuilder builder; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + builder.SetThreadPool(&thread_pool_); + server_ = builder.BuildAndStart(); + } + + void TearDown() GRPC_OVERRIDE { server_->Shutdown(); } + + void ResetStub() { + channel_ = CreateChannel(server_address_.str(), InsecureCredentials(), + ChannelArguments()); + 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_; + TestServiceImpl service_; + ThreadPool thread_pool_; +}; + +// Send a rpc with a normal stub and then a CliCall. Verify they match. +TEST_F(CliCallTest, SimpleRpc) { + ResetStub(); + // Normal stub. + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.IsOk()); + + const grpc::string kMethod("/grpc.cpp.test.util.TestService/Echo"); + grpc::string request_bin, response_bin, expected_response_bin; + EXPECT_TRUE(request.SerializeToString(&request_bin)); + EXPECT_TRUE(response.SerializeToString(&expected_response_bin)); + CliCall::Call(channel_, kMethod, request_bin, &response_bin); + EXPECT_EQ(expected_response_bin, response_bin); +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int result = RUN_ALL_TESTS(); + grpc_shutdown(); + return result; +} diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc new file mode 100644 index 0000000000..f2271d9365 --- /dev/null +++ b/test/cpp/util/grpc_cli.cc @@ -0,0 +1,139 @@ +/* + * + * 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. + * + */ + +/* + A command line tool to talk to any grpc server. + Example of talking to grpc interop server: + 1. Prepare request binary file: + a. create a text file input.txt, containing the following: + response_size: 10 + payload: { + body: "hello world" + } + b. under grpc/ run + protoc --proto_path=test/cpp/interop/ \ + --encode=grpc.testing.SimpleRequest test/cpp/interop/messages.proto \ + < input.txt > input.bin + 2. Start a server + make interop_server && bins/opt/interop_server --port=50051 + 3. Run the tool + make grpc_cli && bins/opt/grpc_cli call localhost:50051 \ + /grpc.testing.TestService/UnaryCall --enable_ssl=false \ + --input_binary_file=input.bin --output_binary_file=output.bin + 4. Decode response + protoc --proto_path=test/cpp/interop/ \ + --decode=grpc.testing.SimpleResponse test/cpp/interop/messages.proto \ + < output.bin > output.txt + 5. Now the text form of response should be in output.txt +*/ + +#include <fstream> +#include <iostream> +#include <sstream> + +#include <gflags/gflags.h> +#include "test/cpp/util/cli_call.h" +#include <grpc++/channel_arguments.h> +#include <grpc++/channel_interface.h> +#include <grpc++/create_channel.h> +#include <grpc++/credentials.h> + +#include <grpc/grpc.h> + +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google {} +namespace gflags {} +using namespace google; +using namespace gflags; + +DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls."); +DEFINE_bool(use_auth, false, "Whether to create default google credentials."); +DEFINE_string(input_binary_file, "", + "Path to input file containing serialized request."); +DEFINE_string(output_binary_file, "output.bin", + "Path to output file to write serialized response."); + +int main(int argc, char** argv) { + grpc_init(); + + ParseCommandLineFlags(&argc, &argv, true); + + if (argc < 4 || grpc::string(argv[1]) != "call") { + std::cout << "Usage: grpc_cli call server_host:port full_method_string\n" + << "Example: grpc_cli call service.googleapis.com " + << "/grpc.testing.TestService/UnaryCall " + << "--input_binary_file=input.bin --output_binary_file=output.bin" + << std::endl; + } + grpc::string server_address(argv[2]); + // TODO(yangg) basic check of method string + grpc::string method(argv[3]); + + if (FLAGS_input_binary_file.empty()) { + std::cout << "Missing --input_binary_file for serialized request." + << std::endl; + return 1; + } + std::cout << "connecting to " << server_address << std::endl; + + std::ifstream input_file(FLAGS_input_binary_file, + std::ios::in | std::ios::binary); + std::stringstream input_stream; + input_stream << input_file.rdbuf(); + + std::unique_ptr<grpc::Credentials> creds; + if (!FLAGS_enable_ssl) { + creds = grpc::InsecureCredentials(); + } else { + if (FLAGS_use_auth) { + creds = grpc::GoogleDefaultCredentials(); + } else { + creds = grpc::SslCredentials(grpc::SslCredentialsOptions()); + } + } + std::shared_ptr<grpc::ChannelInterface> channel = + grpc::CreateChannel(server_address, creds, grpc::ChannelArguments()); + + grpc::string response; + grpc::testing::CliCall::Call(channel, method, input_stream.str(), &response); + if (!response.empty()) { + std::ofstream output_file(FLAGS_output_binary_file, + std::ios::trunc | std::ios::binary); + output_file << response; + } + + channel.reset(); + grpc_shutdown(); + return 0; +} diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto index 9c27f6869e..a79bce1f30 100644 --- a/test/cpp/util/messages.proto +++ b/test/cpp/util/messages.proto @@ -34,6 +34,8 @@ package grpc.cpp.test.util; message RequestParams { optional bool echo_deadline = 1; + optional int32 client_cancel_after_us = 2; + optional int32 server_cancel_after_us = 3; } message EchoRequest { diff --git a/test/cpp/util/time_test.cc b/test/cpp/util/time_test.cc index 2e17add67f..4641fdb4da 100644 --- a/test/cpp/util/time_test.cc +++ b/test/cpp/util/time_test.cc @@ -61,11 +61,24 @@ TEST_F(TimeTest, AbsolutePointTest) { EXPECT_TRUE(tp == tp_converted_2); } -// gpr_inf_future is treated specially and mapped to time_point::max() +// gpr_inf_future is treated specially and mapped to/from time_point::max() TEST_F(TimeTest, InfFuture) { EXPECT_EQ(system_clock::time_point::max(), Timespec2Timepoint(gpr_inf_future)); + gpr_timespec from_time_point_max; + Timepoint2Timespec(system_clock::time_point::max(), &from_time_point_max); + EXPECT_EQ(0, gpr_time_cmp(gpr_inf_future, from_time_point_max)); + // This will cause an overflow + Timepoint2Timespec( + std::chrono::time_point<system_clock, std::chrono::seconds>::max(), + &from_time_point_max); + EXPECT_EQ(0, gpr_time_cmp(gpr_inf_future, from_time_point_max)); } } // namespace } // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/third_party/openssl b/third_party/openssl -Subproject 4ac0329582829f5378d8078c8d314ad37db8773 +Subproject 3df69d3aefde7671053d4e3c242b228e5d79c83 diff --git a/tools/distpackages/build_deb_packages.sh b/tools/distpackages/build_deb_packages.sh index 7b2acb6577..0beb41ed0a 100755 --- a/tools/distpackages/build_deb_packages.sh +++ b/tools/distpackages/build_deb_packages.sh @@ -30,11 +30,28 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # Where to put resulting .deb packages. -deb_dest="deb_out" +set -x +deb_dest="/tmp/deb_out" mkdir -p $deb_dest -version='0.5.0.0' +# Where the grpc disto is +grpc_root="/var/local/git/grpc" + +# Update version from default values if the file /version.txt exists +# +# - when present, /version.txt will added by the docker build. pkg_version='0.5.0' +if [ -f /version.txt ]; then + pkg_version=$(cat /version.txt) +fi +version="${pkg_version}.0" +release_tag="release-${pkg_version//./_}" +echo "Target release => $pkg_version, will checkout tag $release_tag" + +# Switch grpc_root to the release tag +pushd $grpc_root +git checkout $release_tag || { echo "bad release tag ${release_tag}"; exit 1; } +popd if [ -f /.dockerinit ]; then # We're in Docker where uname -p returns "unknown". @@ -64,7 +81,9 @@ do if [ $pkg_name == "libgrpc" ] then # Copy shared libraries - (cd ../..; make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib) + pushd $grpc_root + make install-shared_c prefix=$tmp_dir/$pkg_name/usr/lib + popd mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir # non-dev package should contain so.0 symlinks @@ -77,7 +96,10 @@ do if [ $pkg_name == "libgrpc-dev" ] then # Copy headers and static libraries - (cd ../..; make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib) + pushd $grpc_root + make install-headers_c install-static_c prefix=$tmp_dir/$pkg_name/usr/lib + popd + mv $tmp_dir/$pkg_name/usr/lib/include $tmp_dir/$pkg_name/usr/include mv $tmp_dir/$pkg_name/usr/lib/lib $arch_lib_dir @@ -110,8 +132,5 @@ do dpkg-deb -c $deb_path echo "Problems reported by lintian:" lintian $deb_path - echo done - - diff --git a/tools/distpackages/templates/libgrpc/DEBIAN/control b/tools/distpackages/templates/libgrpc/DEBIAN/control index 417a825827..5854b1f4a1 100644 --- a/tools/distpackages/templates/libgrpc/DEBIAN/control +++ b/tools/distpackages/templates/libgrpc/DEBIAN/control @@ -2,7 +2,8 @@ Package: libgrpc Version: 0.5.0 Architecture: amd64 Maintainer: Jan Tattermusch <jtattermusch@google.com> -Depends: libc6 +Depends: libc6, openssl (1.0.2-1) +Build-Depends-Indep: openssl (1.0.2-1) Section: libs Priority: optional Homepage: https://github.com/grpc/grpc diff --git a/tools/distrib/python/submit.py b/tools/distrib/python/submit.py new file mode 100755 index 0000000000..79ebb93e57 --- /dev/null +++ b/tools/distrib/python/submit.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python + +import argparse +import os +import shutil +import subprocess + +parser = argparse.ArgumentParser( + description='Submit the package to a PyPI repository.') +parser.add_argument( + '--repository', '-r', metavar='r', type=str, default='pypi', + help='The repository to push the package to. ' + 'Ensure the value appears in your .pypirc file. ' + 'Defaults to "pypi".' +) +parser.add_argument( + '--identity', '-i', metavar='i', type=str, + help='GPG identity to sign the files with.' +) +parser.add_argument( + '--username', '-u', metavar='u', type=str, + help='Username to authenticate with the repository. Not needed if you have ' + 'configured your .pypirc to include your username.' +) +parser.add_argument( + '--password', '-p', metavar='p', type=str, + help='Password to authenticate with the repository. Not needed if you have ' + 'configured your .pypirc to include your password.' +) +args = parser.parse_args() + +# Move to the root directory of Python GRPC. +pkgdir = os.path.join(os.path.dirname(os.path.abspath(__file__)), + '../../../src/python/src') +# Remove previous distributions; they somehow confuse twine. +try: + shutil.rmtree(os.path.join(pkgdir, 'dist/')) +except: + pass + +# Make the push. +cmd = ['python', 'setup.py', 'sdist'] +subprocess.call(cmd, cwd=pkgdir) + +cmd = ['twine', 'upload', '-r', args.repository] +if args.identity is not None: + cmd.extend(['-i', args.identity]) +if args.username is not None: + cmd.extend(['-u', args.username]) +if args.password is not None: + cmd.extend(['-p', args.password]) +cmd.append('dist/*') + +subprocess.call(cmd, cwd=pkgdir) diff --git a/tools/dockerfile/grpc_build_deb/Dockerfile b/tools/dockerfile/grpc_build_deb/Dockerfile index 24ffc7379c..7f025b6712 100644 --- a/tools/dockerfile/grpc_build_deb/Dockerfile +++ b/tools/dockerfile/grpc_build_deb/Dockerfile @@ -30,8 +30,17 @@ # Dockerfile to build Debian packages for gRPC C core. FROM grpc/base +# Add the file containing the gRPC version +ADD version.txt version.txt + +# Add the update-to-date distpackages folder +ADD distpackages distpackages + # Install dependencies -RUN apt-get update && apt-get install -y lintian +RUN echo 'deb http://http.debian.net/debian experimental main contrib non-free' >> /etc/apt/sources.list +RUN apt-get update \ + && apt-get -t experimental install -y openssl=1.0.2-1 \ + && apt-get install -y lintian # Get the source from GitHub RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc @@ -39,4 +48,4 @@ RUN cd /var/local/git/grpc && \ git pull --recurse-submodules && \ git submodule update --init --recursive -RUN /bin/bash -l -c 'cd /var/local/git/grpc/tools/distpackages && ./build_deb_packages.sh' +RUN /bin/bash -l -c 'cd /distpackages && ./build_deb_packages.sh' diff --git a/tools/dockerfile/grpc_build_deb/version.txt b/tools/dockerfile/grpc_build_deb/version.txt new file mode 100644 index 0000000000..a918a2aa18 --- /dev/null +++ b/tools/dockerfile/grpc_build_deb/version.txt @@ -0,0 +1 @@ +0.6.0 diff --git a/tools/dockerfile/grpc_dist_proto/version.txt b/tools/dockerfile/grpc_dist_proto/version.txt index 8f0916f768..a918a2aa18 100644 --- a/tools/dockerfile/grpc_dist_proto/version.txt +++ b/tools/dockerfile/grpc_dist_proto/version.txt @@ -1 +1 @@ -0.5.0 +0.6.0 diff --git a/tools/dockerfile/grpc_java_base/Dockerfile b/tools/dockerfile/grpc_java_base/Dockerfile index 2ee0a623c7..57b1b90fcd 100644 --- a/tools/dockerfile/grpc_java_base/Dockerfile +++ b/tools/dockerfile/grpc_java_base/Dockerfile @@ -57,8 +57,6 @@ RUN wget -O - https://github.com/google/protobuf/archive/v3.0.0-alpha-2.tar.gz | ./autogen.sh && \ ./configure --prefix=/usr && \ make -j12 && make check && make install && \ - cd java && mvn install && cd .. && \ - cd javanano && mvn install && cd .. && \ rm -r "$(pwd)" # Trigger download of as many Maven and Gradle artifacts as possible. We don't build grpc-java diff --git a/tools/dockerfile/grpc_php/Dockerfile b/tools/dockerfile/grpc_php/Dockerfile index 100d7b3bdb..770d0d2627 100644 --- a/tools/dockerfile/grpc_php/Dockerfile +++ b/tools/dockerfile/grpc_php/Dockerfile @@ -45,3 +45,9 @@ RUN cd /var/local/git/grpc/src/php/ext/grpc && git pull && phpize RUN cd /var/local/git/grpc/src/php/ext/grpc \ && ./configure \ && make + +RUN cd /var/local/git/grpc/src/php && composer install + +RUN cd /var/local/git/grpc/src/php && protoc-gen-php -i tests/interop/ -o tests/interop/ tests/interop/test.proto + +RUN cd /var/local/git/grpc/src/php && ./bin/run_tests.sh
\ No newline at end of file diff --git a/tools/dockerfile/grpc_php_base/Dockerfile b/tools/dockerfile/grpc_php_base/Dockerfile index cc874fd7c5..c49d3fef66 100644 --- a/tools/dockerfile/grpc_php_base/Dockerfile +++ b/tools/dockerfile/grpc_php_base/Dockerfile @@ -32,6 +32,10 @@ # Includes PHP installation dependencies, things that are unlikely to vary. FROM grpc/base +RUN echo "deb http://packages.dotdeb.org wheezy-php55 all" >> /etc/apt/sources.list.d/dotdeb.list +RUN echo "deb-src http://packages.dotdeb.org wheezy-php55 all" >> /etc/apt/sources.list.d/dotdeb.list +RUN wget http://www.dotdeb.org/dotdeb.gpg -O- |apt-key add - + # Install RVM dependencies and other packages RUN apt-get update && apt-get install -y \ autoconf \ @@ -50,29 +54,25 @@ RUN apt-get update && apt-get install -y \ libsqlite3-dev \ libssl-dev \ libtool \ + libxml2 \ libyaml-dev \ make \ patch \ procps \ -# TODO(mlumish): Uncomment these lines when building against them works -# php5-common \ -# php5-cli \ -# php5-dev \ -# php-pear \ + php5-common \ + php5-cli \ + php5-dev \ + php-pear \ pkg-config \ procps \ sqlite3 \ zlib1g-dev -# Install the version of PHP gRPC is tested against ENV DEBIAN_FRONTEND noniteractive -RUN apt-get update && apt-get install -y libxml2 libxml2-dev # used by PHP -RUN cd /var/local \ - && curl -o php-5.5.17.tar.gz http://php.net/distributions/php-5.5.17.tar.gz \ - && tar -xf php-5.5.17.tar.gz \ - && cd php-5.5.17 \ - && ./configure --with-zlib=/usr --with-libxml-dir=ext/libxml \ - && make -j12 && make install + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php +RUN mv composer.phar /usr/local/bin/composer # Download the patched PHP protobuf so that PHP gRPC clients can be generated # from proto3 schemas. diff --git a/tools/dockerfile/grpc_scan_build/Dockerfile b/tools/dockerfile/grpc_scan_build/Dockerfile new file mode 100644 index 0000000000..9f263849c9 --- /dev/null +++ b/tools/dockerfile/grpc_scan_build/Dockerfile @@ -0,0 +1,47 @@ +# 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. + +FROM grpc/clang:latest + +RUN apt-get update && apt-get install -y \ + autoconf \ + libtool \ + libgflags-dev \ + libgtest-dev \ + && apt-get clean + +RUN git clone --recursive https://github.com/grpc/grpc.git + +EXPOSE 8181 + +CMD \ + (cd grpc ; git pull) && \ + (cd grpc ; git submodule update --init --recursive) && \ + llvm/tools/clang/tools/scan-build/scan-build -o /tmp/grpc --use-analyzer=/usr/local/bin/clang make -C grpc buildtests && \ + llvm/tools/clang/tools/scan-view/scan-view /tmp/grpc/`ls /tmp/grpc` --host 0.0.0.0 --no-browser --allow-all-hosts diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 497112ce39..40634291cf 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -673,7 +673,7 @@ _grpc_build_proto_bins_args() { } # grpc_build_proto_bins -# +# # - rebuilds the dist_proto docker image # * doing this builds the protoc and the ruby, python and cpp bins statically # @@ -693,11 +693,11 @@ grpc_build_proto_bins() { gce_has_instance $grpc_project $host || return 1; local project_opt="--project $grpc_project" local zone_opt="--zone $grpc_zone" - + # rebuild the dist_proto image local label='dist_proto' grpc_update_image -- -h $host $label || return 1 - + # run a command to copy the generated archive to the docker host local docker_prefix='sudo docker run -v /tmp:/tmp/proto_bins_out' local tar_name='proto-bins*.tar.gz' @@ -715,6 +715,63 @@ grpc_build_proto_bins() { gcloud compute copy-files $rmt_tar $local_copy $project_opt $zone_opt || return 1 } +_grpc_build_debs_args() { + [[ -n $1 ]] && { # host + host=$1 + shift + } || { + host='grpc-docker-builder' + } +} + +# grpc_build_debs +# +# - rebuilds the build_debs +# * doing this builds a deb package for release debs +# +# - runs a docker command that copies the debs from the docker instance to its +# host +# - copies the debs from the host to the local machine +grpc_build_debs() { + _grpc_ensure_gcloud_ssh || return 1; + + # declare vars local so that they don't pollute the shell environment + # where this func is used. + local grpc_zone grpc_project dry_run # set by _grpc_set_project_and_zone + # set by _grpc_build_debs_args + local host + + # set the project zone and check that all necessary args are provided + _grpc_set_project_and_zone -f _grpc_build_debs_args "$@" || return 1 + gce_has_instance $grpc_project $host || return 1; + local project_opt="--project $grpc_project" + local zone_opt="--zone $grpc_zone" + + # Update the remote distpackages_dir + local src_dist_dir='tools/distpackages' + local rmt_dist_dir="$host:~" + gcloud compute copy-files $src_dist_dir $rmt_dist_dir $project_opt $zone_opt || return 1 + + # rebuild the build_deb image + local label='build_deb' + grpc_update_image -- -h $host $label || return 1 + + # run a command to copy the debs from the docker instance to the host. + local docker_prefix='sudo docker run -v /tmp:/tmp/host_deb_out' + local cp_cmd="/bin/bash -c 'cp -v /tmp/deb_out/*.deb /tmp/host_deb_out'" + local cmd="$docker_prefix grpc/$label $cp_cmd" + local ssh_cmd="bash -l -c \"$cmd\"" + echo "will run:" + echo " $ssh_cmd" + echo "on $host" + gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" || return 1 + + # copy the debs from host machine to the local one. + local rmt_debs="$host:/tmp/*.deb" + local local_copy="$(pwd)" + gcloud compute copy-files $rmt_debs $local_copy $project_opt $zone_opt || return 1 +} + _grpc_launch_servers_args() { [[ -n $1 ]] && { # host host=$1 @@ -984,6 +1041,35 @@ grpc_interop_gen_python_cmd() { echo $the_cmd } +# constructs the full dockerized python service_account auth interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_service_account_creds_gen_python_cmd() { + local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c"; + local gfe_flags=$(_grpc_prod_gfe_flags) + local added_gfe_flags=$(_grpc_default_creds_test_flags) + local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" + env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json" + local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'" + echo $the_cmd +} + +# constructs the full dockerized python gce auth interop test cmd. +# +# call-seq: +# flags= .... # generic flags to include the command +# cmd=$($grpc_gen_test_cmd $flags) +grpc_cloud_prod_auth_compute_engine_creds_gen_python_cmd() { + local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c"; + local gfe_flags=$(_grpc_prod_gfe_flags) + local added_gfe_flags=$(_grpc_gce_test_flags) + local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" + local the_cmd="$cmd_prefix '$env_prefix python -B -m interop.client --use_tls $gfe_flags $added_gfe_flags $@'" + echo $the_cmd +} + # constructs the full dockerized java interop test cmd. # # call-seq: @@ -1310,5 +1396,3 @@ _grpc_default_creds_test_flags() { _grpc_gce_test_flags() { echo " --default_service_account=155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel@developer.gserviceaccount.com --oauth_scope=https://www.googleapis.com/auth/xapi.zoo" } - -# TODO(grpc-team): add grpc_interop_gen_xxx_cmd for python diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh index 7f0b5bab1a..1c6122e9ae 100755 --- a/tools/gce_setup/interop_test_runner.sh +++ b/tools/gce_setup/interop_test_runner.sh @@ -36,7 +36,7 @@ echo $result_file_name main() { source grpc_docker.sh test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response) - clients=(cxx java go ruby node python csharp_mono) + clients=(cxx java go ruby node python csharp_mono php) servers=(cxx java go ruby node python csharp_mono) for test_case in "${test_cases[@]}" do diff --git a/tools/gce_setup/shared_startup_funcs.sh b/tools/gce_setup/shared_startup_funcs.sh index e6eecc56db..c4a076757a 100755 --- a/tools/gce_setup/shared_startup_funcs.sh +++ b/tools/gce_setup/shared_startup_funcs.sh @@ -434,6 +434,12 @@ grpc_dockerfile_install() { grpc_docker_sync_service_account $dockerfile_dir/service_account || return 1; } + # For deb builds, copy the distpackages folder into the docker directory so + # that it can be installed using ADD distpackages distpackages. + [[ $image_label == "grpc/build_deb" ]] && { + cp -vR ~/distpackages $dockerfile_dir + } + # TODO(temiola): maybe make cache/no-cache a func option? sudo docker build $cache_opt -t $image_label $dockerfile_dir || { echo "$FUNCNAME:: build of $image_label <- $dockerfile_dir" diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 6b8cd1111e..14ee1790c6 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -224,6 +224,24 @@ class CSharpLanguage(object): def __str__(self): return 'csharp' +class Build(object): + + def test_specs(self, config, travis): + return [] + + def make_targets(self): + return ['all'] + + def build_steps(self): + return [] + + def supports_multi_config(self): + return True + + def __str__(self): + return self.make_target + + # different configurations we can run under _CONFIGS = { 'dbg': SimpleConfig('dbg'), @@ -248,7 +266,8 @@ _LANGUAGES = { 'php': PhpLanguage(), 'python': PythonLanguage(), 'ruby': RubyLanguage(), - 'csharp': CSharpLanguage() + 'csharp': CSharpLanguage(), + 'build': Build(), } # parse command line diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 355d5735cd..eab07040e7 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -349,11 +349,21 @@ { "flaky": false, "language": "c++", + "name": "cli_call_test" + }, + { + "flaky": false, + "language": "c++", "name": "credentials_test" }, { "flaky": false, "language": "c++", + "name": "cxx_time_test" + }, + { + "flaky": false, + "language": "c++", "name": "end2end_test" }, { diff --git a/vsprojects/vs2010/Grpc.mak b/vsprojects/vs2010/Grpc.mak new file mode 100644 index 0000000000..203c787287 --- /dev/null +++ b/vsprojects/vs2010/Grpc.mak @@ -0,0 +1,712 @@ +# 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. +# NMake file to build secondary gRPC targets on Windows. +# Use grpc.sln to solution to build the gRPC libraries. + +OUT_DIR=test_bin + +CC=cl.exe +LINK=link.exe + +INCLUDES=/I..\.. /I..\..\include /I..\..\third_party\zlib /I..\third_party /I..\..\third_party\openssl\inc32 +DEFINES=/D WIN32 /D _LIB /D _USE_32BIT_TIME_T /D _UNICODE /D UNICODE /D _CRT_SECURE_NO_WARNINGS +CFLAGS=/c $(INCLUDES) /nologo /Z7 /W3 /WX- /sdl $(DEFINES) /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /analyze- +LFLAGS=/DEBUG /INCREMENTAL /NOLOGO /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 + +OPENSSL_LIBS=..\..\third_party\openssl\out32\ssleay32.lib ..\..\third_party\openssl\out32\libeay32.lib +WINSOCK_LIBS=ws2_32.lib +ZLIB_LIBS=Debug\zlibwapi.lib +LIBS=$(OPENSSL_LIBS) $(WINSOCK_LIBS) $(ZLIB_LIBS) + +gpr_test_util: + MSBuild.exe gpr_test_util.vcxproj /p:Configuration=Debug + +grpc_test_util: + MSBuild.exe grpc_test_util.vcxproj /p:Configuration=Debug + +$(OUT_DIR): + mkdir $(OUT_DIR) + +buildtests: alarm_heap_test.exe alarm_list_test.exe alarm_test.exe alpn_test.exe bin_encoder_test.exe census_hash_table_test.exe census_statistics_multiple_writers_circular_buffer_test.exe census_statistics_multiple_writers_test.exe census_statistics_performance_test.exe census_statistics_quick_test.exe census_statistics_small_log_test.exe census_stats_store_test.exe census_stub_test.exe census_trace_store_test.exe census_window_stats_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe chttp2_transport_end2end_test.exe dualstack_socket_test.exe echo_test.exe fd_posix_test.exe fling_stream_test.exe fling_test.exe gpr_cancellable_test.exe gpr_cmdline_test.exe gpr_env_test.exe gpr_file_test.exe gpr_histogram_test.exe gpr_host_port_test.exe gpr_log_test.exe gpr_slice_buffer_test.exe gpr_slice_test.exe gpr_string_test.exe gpr_sync_test.exe gpr_thd_test.exe gpr_time_test.exe gpr_useful_test.exe grpc_base64_test.exe grpc_byte_buffer_reader_test.exe grpc_channel_stack_test.exe grpc_completion_queue_test.exe grpc_credentials_test.exe grpc_json_token_test.exe grpc_stream_op_test.exe hpack_parser_test.exe hpack_table_test.exe httpcli_format_request_test.exe httpcli_parser_test.exe httpcli_test.exe json_rewrite_test.exe json_test.exe lame_client_test.exe message_compress_test.exe metadata_buffer_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe poll_kick_posix_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe tcp_client_posix_test.exe tcp_posix_test.exe tcp_server_posix_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe transport_metadata_test.exe transport_security_test.exe + echo All tests built. + +test: alarm_heap_test alarm_list_test alarm_test alpn_test bin_encoder_test census_hash_table_test census_statistics_multiple_writers_circular_buffer_test census_statistics_multiple_writers_test census_statistics_performance_test census_statistics_quick_test census_statistics_small_log_test census_stats_store_test census_stub_test census_trace_store_test census_window_stats_test chttp2_status_conversion_test chttp2_stream_encoder_test chttp2_stream_map_test chttp2_transport_end2end_test dualstack_socket_test echo_test fd_posix_test fling_stream_test fling_test gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test grpc_base64_test grpc_byte_buffer_reader_test grpc_channel_stack_test grpc_completion_queue_test grpc_credentials_test grpc_json_token_test grpc_stream_op_test hpack_parser_test hpack_table_test httpcli_format_request_test httpcli_parser_test httpcli_test json_rewrite_test json_test lame_client_test message_compress_test metadata_buffer_test multi_init_test murmur_hash_test no_server_test poll_kick_posix_test resolve_address_test secure_endpoint_test sockaddr_utils_test tcp_client_posix_test tcp_posix_test tcp_server_posix_test time_averaged_stats_test time_test timeout_encoding_test transport_metadata_test transport_security_test + echo All tests ran. + +test_gpr: gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test + echo All tests ran. + +alarm_heap_test.exe: grpc_test_util + echo Building alarm_heap_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\alarm_heap_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alarm_heap_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alarm_heap_test.obj +alarm_heap_test: alarm_heap_test.exe + echo Running alarm_heap_test + $(OUT_DIR)\alarm_heap_test.exe + +alarm_list_test.exe: grpc_test_util + echo Building alarm_list_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\alarm_list_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alarm_list_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alarm_list_test.obj +alarm_list_test: alarm_list_test.exe + echo Running alarm_list_test + $(OUT_DIR)\alarm_list_test.exe + +alarm_test.exe: grpc_test_util + echo Building alarm_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\alarm_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alarm_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alarm_test.obj +alarm_test: alarm_test.exe + echo Running alarm_test + $(OUT_DIR)\alarm_test.exe + +alpn_test.exe: grpc_test_util + echo Building alpn_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\alpn_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\alpn_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\alpn_test.obj +alpn_test: alpn_test.exe + echo Running alpn_test + $(OUT_DIR)\alpn_test.exe + +bin_encoder_test.exe: grpc_test_util + echo Building bin_encoder_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\bin_encoder_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\bin_encoder_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\bin_encoder_test.obj +bin_encoder_test: bin_encoder_test.exe + echo Running bin_encoder_test + $(OUT_DIR)\bin_encoder_test.exe + +census_hash_table_test.exe: grpc_test_util + echo Building census_hash_table_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\hash_table_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_hash_table_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\hash_table_test.obj +census_hash_table_test: census_hash_table_test.exe + echo Running census_hash_table_test + $(OUT_DIR)\census_hash_table_test.exe + +census_statistics_multiple_writers_circular_buffer_test.exe: grpc_test_util + echo Building census_statistics_multiple_writers_circular_buffer_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\multiple_writers_circular_buffer_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_multiple_writers_circular_buffer_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multiple_writers_circular_buffer_test.obj +census_statistics_multiple_writers_circular_buffer_test: census_statistics_multiple_writers_circular_buffer_test.exe + echo Running census_statistics_multiple_writers_circular_buffer_test + $(OUT_DIR)\census_statistics_multiple_writers_circular_buffer_test.exe + +census_statistics_multiple_writers_test.exe: grpc_test_util + echo Building census_statistics_multiple_writers_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\multiple_writers_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_multiple_writers_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multiple_writers_test.obj +census_statistics_multiple_writers_test: census_statistics_multiple_writers_test.exe + echo Running census_statistics_multiple_writers_test + $(OUT_DIR)\census_statistics_multiple_writers_test.exe + +census_statistics_performance_test.exe: grpc_test_util + echo Building census_statistics_performance_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\performance_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_performance_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\performance_test.obj +census_statistics_performance_test: census_statistics_performance_test.exe + echo Running census_statistics_performance_test + $(OUT_DIR)\census_statistics_performance_test.exe + +census_statistics_quick_test.exe: grpc_test_util + echo Building census_statistics_quick_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\quick_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_quick_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\quick_test.obj +census_statistics_quick_test: census_statistics_quick_test.exe + echo Running census_statistics_quick_test + $(OUT_DIR)\census_statistics_quick_test.exe + +census_statistics_small_log_test.exe: grpc_test_util + echo Building census_statistics_small_log_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\small_log_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_small_log_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\small_log_test.obj +census_statistics_small_log_test: census_statistics_small_log_test.exe + echo Running census_statistics_small_log_test + $(OUT_DIR)\census_statistics_small_log_test.exe + +census_stats_store_test.exe: grpc_test_util + echo Building census_stats_store_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\rpc_stats_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_stats_store_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\rpc_stats_test.obj +census_stats_store_test: census_stats_store_test.exe + echo Running census_stats_store_test + $(OUT_DIR)\census_stats_store_test.exe + +census_stub_test.exe: grpc_test_util + echo Building census_stub_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\census_stub_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_stub_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\census_stub_test.obj +census_stub_test: census_stub_test.exe + echo Running census_stub_test + $(OUT_DIR)\census_stub_test.exe + +census_trace_store_test.exe: grpc_test_util + echo Building census_trace_store_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\trace_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_trace_store_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\trace_test.obj +census_trace_store_test: census_trace_store_test.exe + echo Running census_trace_store_test + $(OUT_DIR)\census_trace_store_test.exe + +census_window_stats_test.exe: grpc_test_util + echo Building census_window_stats_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\statistics\window_stats_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_window_stats_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\window_stats_test.obj +census_window_stats_test: census_window_stats_test.exe + echo Running census_window_stats_test + $(OUT_DIR)\census_window_stats_test.exe + +chttp2_status_conversion_test.exe: grpc_test_util + echo Building chttp2_status_conversion_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\status_conversion_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_status_conversion_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\status_conversion_test.obj +chttp2_status_conversion_test: chttp2_status_conversion_test.exe + echo Running chttp2_status_conversion_test + $(OUT_DIR)\chttp2_status_conversion_test.exe + +chttp2_stream_encoder_test.exe: grpc_test_util + echo Building chttp2_stream_encoder_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\stream_encoder_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_stream_encoder_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\stream_encoder_test.obj +chttp2_stream_encoder_test: chttp2_stream_encoder_test.exe + echo Running chttp2_stream_encoder_test + $(OUT_DIR)\chttp2_stream_encoder_test.exe + +chttp2_stream_map_test.exe: grpc_test_util + echo Building chttp2_stream_map_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\stream_map_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_stream_map_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\stream_map_test.obj +chttp2_stream_map_test: chttp2_stream_map_test.exe + echo Running chttp2_stream_map_test + $(OUT_DIR)\chttp2_stream_map_test.exe + +chttp2_transport_end2end_test.exe: grpc_test_util + echo Building chttp2_transport_end2end_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2_transport_end2end_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\chttp2_transport_end2end_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\chttp2_transport_end2end_test.obj +chttp2_transport_end2end_test: chttp2_transport_end2end_test.exe + echo Running chttp2_transport_end2end_test + $(OUT_DIR)\chttp2_transport_end2end_test.exe + +dualstack_socket_test.exe: grpc_test_util + echo Building dualstack_socket_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\end2end\dualstack_socket_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\dualstack_socket_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\dualstack_socket_test.obj +dualstack_socket_test: dualstack_socket_test.exe + echo Running dualstack_socket_test + $(OUT_DIR)\dualstack_socket_test.exe + +echo_client.exe: grpc_test_util + echo Building echo_client + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\echo\client.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\echo_client.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\client.obj +echo_client: echo_client.exe + echo Running echo_client + $(OUT_DIR)\echo_client.exe + +echo_server.exe: grpc_test_util + echo Building echo_server + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\echo\server.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\echo_server.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\server.obj +echo_server: echo_server.exe + echo Running echo_server + $(OUT_DIR)\echo_server.exe + +echo_test.exe: grpc_test_util + echo Building echo_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\echo\echo_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\echo_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\echo_test.obj +echo_test: echo_test.exe + echo Running echo_test + $(OUT_DIR)\echo_test.exe + +fd_posix_test.exe: grpc_test_util + echo Building fd_posix_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\fd_posix_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fd_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fd_posix_test.obj +fd_posix_test: fd_posix_test.exe + echo Running fd_posix_test + $(OUT_DIR)\fd_posix_test.exe + +fling_client.exe: grpc_test_util + echo Building fling_client + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\client.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_client.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\client.obj +fling_client: fling_client.exe + echo Running fling_client + $(OUT_DIR)\fling_client.exe + +fling_server.exe: grpc_test_util + echo Building fling_server + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\server.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_server.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\server.obj +fling_server: fling_server.exe + echo Running fling_server + $(OUT_DIR)\fling_server.exe + +fling_stream_test.exe: grpc_test_util + echo Building fling_stream_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\fling_stream_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_stream_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fling_stream_test.obj +fling_stream_test: fling_stream_test.exe + echo Running fling_stream_test + $(OUT_DIR)\fling_stream_test.exe + +fling_test.exe: grpc_test_util + echo Building fling_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\fling\fling_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\fling_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fling_test.obj +fling_test: fling_test.exe + echo Running fling_test + $(OUT_DIR)\fling_test.exe + +gen_hpack_tables.exe: grpc_test_util + echo Building gen_hpack_tables + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\src\core\transport\chttp2\gen_hpack_tables.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gen_hpack_tables.exe" Debug\grpc_test_util.lib Debug\gpr.lib Debug\grpc.lib $(LIBS) $(OUT_DIR)\gen_hpack_tables.obj +gen_hpack_tables: gen_hpack_tables.exe + echo Running gen_hpack_tables + $(OUT_DIR)\gen_hpack_tables.exe + +gpr_cancellable_test.exe: grpc_test_util + echo Building gpr_cancellable_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\cancellable_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_cancellable_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\cancellable_test.obj +gpr_cancellable_test: gpr_cancellable_test.exe + echo Running gpr_cancellable_test + $(OUT_DIR)\gpr_cancellable_test.exe + +gpr_cmdline_test.exe: grpc_test_util + echo Building gpr_cmdline_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\cmdline_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_cmdline_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\cmdline_test.obj +gpr_cmdline_test: gpr_cmdline_test.exe + echo Running gpr_cmdline_test + $(OUT_DIR)\gpr_cmdline_test.exe + +gpr_env_test.exe: grpc_test_util + echo Building gpr_env_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\env_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_env_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\env_test.obj +gpr_env_test: gpr_env_test.exe + echo Running gpr_env_test + $(OUT_DIR)\gpr_env_test.exe + +gpr_file_test.exe: grpc_test_util + echo Building gpr_file_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\file_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_file_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\file_test.obj +gpr_file_test: gpr_file_test.exe + echo Running gpr_file_test + $(OUT_DIR)\gpr_file_test.exe + +gpr_histogram_test.exe: grpc_test_util + echo Building gpr_histogram_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\histogram_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_histogram_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\histogram_test.obj +gpr_histogram_test: gpr_histogram_test.exe + echo Running gpr_histogram_test + $(OUT_DIR)\gpr_histogram_test.exe + +gpr_host_port_test.exe: grpc_test_util + echo Building gpr_host_port_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\host_port_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_host_port_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\host_port_test.obj +gpr_host_port_test: gpr_host_port_test.exe + echo Running gpr_host_port_test + $(OUT_DIR)\gpr_host_port_test.exe + +gpr_log_test.exe: grpc_test_util + echo Building gpr_log_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\log_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_log_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\log_test.obj +gpr_log_test: gpr_log_test.exe + echo Running gpr_log_test + $(OUT_DIR)\gpr_log_test.exe + +gpr_slice_buffer_test.exe: grpc_test_util + echo Building gpr_slice_buffer_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\slice_buffer_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_slice_buffer_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\slice_buffer_test.obj +gpr_slice_buffer_test: gpr_slice_buffer_test.exe + echo Running gpr_slice_buffer_test + $(OUT_DIR)\gpr_slice_buffer_test.exe + +gpr_slice_test.exe: grpc_test_util + echo Building gpr_slice_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\slice_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_slice_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\slice_test.obj +gpr_slice_test: gpr_slice_test.exe + echo Running gpr_slice_test + $(OUT_DIR)\gpr_slice_test.exe + +gpr_string_test.exe: grpc_test_util + echo Building gpr_string_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\string_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_string_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\string_test.obj +gpr_string_test: gpr_string_test.exe + echo Running gpr_string_test + $(OUT_DIR)\gpr_string_test.exe + +gpr_sync_test.exe: grpc_test_util + echo Building gpr_sync_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\sync_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_sync_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\sync_test.obj +gpr_sync_test: gpr_sync_test.exe + echo Running gpr_sync_test + $(OUT_DIR)\gpr_sync_test.exe + +gpr_thd_test.exe: grpc_test_util + echo Building gpr_thd_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\thd_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_thd_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\thd_test.obj +gpr_thd_test: gpr_thd_test.exe + echo Running gpr_thd_test + $(OUT_DIR)\gpr_thd_test.exe + +gpr_time_test.exe: grpc_test_util + echo Building gpr_time_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\time_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_time_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\time_test.obj +gpr_time_test: gpr_time_test.exe + echo Running gpr_time_test + $(OUT_DIR)\gpr_time_test.exe + +gpr_useful_test.exe: grpc_test_util + echo Building gpr_useful_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\useful_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\gpr_useful_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\useful_test.obj +gpr_useful_test: gpr_useful_test.exe + echo Running gpr_useful_test + $(OUT_DIR)\gpr_useful_test.exe + +grpc_base64_test.exe: grpc_test_util + echo Building grpc_base64_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\base64_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_base64_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\base64_test.obj +grpc_base64_test: grpc_base64_test.exe + echo Running grpc_base64_test + $(OUT_DIR)\grpc_base64_test.exe + +grpc_byte_buffer_reader_test.exe: grpc_test_util + echo Building grpc_byte_buffer_reader_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\byte_buffer_reader_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_byte_buffer_reader_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\byte_buffer_reader_test.obj +grpc_byte_buffer_reader_test: grpc_byte_buffer_reader_test.exe + echo Running grpc_byte_buffer_reader_test + $(OUT_DIR)\grpc_byte_buffer_reader_test.exe + +grpc_channel_stack_test.exe: grpc_test_util + echo Building grpc_channel_stack_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\channel\channel_stack_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_channel_stack_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\channel_stack_test.obj +grpc_channel_stack_test: grpc_channel_stack_test.exe + echo Running grpc_channel_stack_test + $(OUT_DIR)\grpc_channel_stack_test.exe + +grpc_completion_queue_benchmark.exe: grpc_test_util + echo Building grpc_completion_queue_benchmark + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\completion_queue_benchmark.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_completion_queue_benchmark.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\completion_queue_benchmark.obj +grpc_completion_queue_benchmark: grpc_completion_queue_benchmark.exe + echo Running grpc_completion_queue_benchmark + $(OUT_DIR)\grpc_completion_queue_benchmark.exe + +grpc_completion_queue_test.exe: grpc_test_util + echo Building grpc_completion_queue_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\completion_queue_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_completion_queue_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\completion_queue_test.obj +grpc_completion_queue_test: grpc_completion_queue_test.exe + echo Running grpc_completion_queue_test + $(OUT_DIR)\grpc_completion_queue_test.exe + +grpc_create_jwt.exe: grpc_test_util + echo Building grpc_create_jwt + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\create_jwt.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_create_jwt.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\create_jwt.obj +grpc_create_jwt: grpc_create_jwt.exe + echo Running grpc_create_jwt + $(OUT_DIR)\grpc_create_jwt.exe + +grpc_credentials_test.exe: grpc_test_util + echo Building grpc_credentials_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\credentials_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_credentials_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\credentials_test.obj +grpc_credentials_test: grpc_credentials_test.exe + echo Running grpc_credentials_test + $(OUT_DIR)\grpc_credentials_test.exe + +grpc_fetch_oauth2.exe: grpc_test_util + echo Building grpc_fetch_oauth2 + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\fetch_oauth2.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_fetch_oauth2.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\fetch_oauth2.obj +grpc_fetch_oauth2: grpc_fetch_oauth2.exe + echo Running grpc_fetch_oauth2 + $(OUT_DIR)\grpc_fetch_oauth2.exe + +grpc_json_token_test.exe: grpc_test_util + echo Building grpc_json_token_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\json_token_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_json_token_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_token_test.obj +grpc_json_token_test: grpc_json_token_test.exe + echo Running grpc_json_token_test + $(OUT_DIR)\grpc_json_token_test.exe + +grpc_print_google_default_creds_token.exe: grpc_test_util + echo Building grpc_print_google_default_creds_token + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\print_google_default_creds_token.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_print_google_default_creds_token.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\print_google_default_creds_token.obj +grpc_print_google_default_creds_token: grpc_print_google_default_creds_token.exe + echo Running grpc_print_google_default_creds_token + $(OUT_DIR)\grpc_print_google_default_creds_token.exe + +grpc_stream_op_test.exe: grpc_test_util + echo Building grpc_stream_op_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\stream_op_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\grpc_stream_op_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\stream_op_test.obj +grpc_stream_op_test: grpc_stream_op_test.exe + echo Running grpc_stream_op_test + $(OUT_DIR)\grpc_stream_op_test.exe + +hpack_parser_test.exe: grpc_test_util + echo Building hpack_parser_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\hpack_parser_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\hpack_parser_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\hpack_parser_test.obj +hpack_parser_test: hpack_parser_test.exe + echo Running hpack_parser_test + $(OUT_DIR)\hpack_parser_test.exe + +hpack_table_test.exe: grpc_test_util + echo Building hpack_table_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\hpack_table_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\hpack_table_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\hpack_table_test.obj +hpack_table_test: hpack_table_test.exe + echo Running hpack_table_test + $(OUT_DIR)\hpack_table_test.exe + +httpcli_format_request_test.exe: grpc_test_util + echo Building httpcli_format_request_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\httpcli\format_request_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\httpcli_format_request_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\format_request_test.obj +httpcli_format_request_test: httpcli_format_request_test.exe + echo Running httpcli_format_request_test + $(OUT_DIR)\httpcli_format_request_test.exe + +httpcli_parser_test.exe: grpc_test_util + echo Building httpcli_parser_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\httpcli\parser_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\httpcli_parser_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\parser_test.obj +httpcli_parser_test: httpcli_parser_test.exe + echo Running httpcli_parser_test + $(OUT_DIR)\httpcli_parser_test.exe + +httpcli_test.exe: grpc_test_util + echo Building httpcli_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\httpcli\httpcli_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\httpcli_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\httpcli_test.obj +httpcli_test: httpcli_test.exe + echo Running httpcli_test + $(OUT_DIR)\httpcli_test.exe + +json_rewrite.exe: grpc_test_util + echo Building json_rewrite + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\json\json_rewrite.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\json_rewrite.exe" Debug\grpc.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_rewrite.obj +json_rewrite: json_rewrite.exe + echo Running json_rewrite + $(OUT_DIR)\json_rewrite.exe + +json_rewrite_test.exe: grpc_test_util + echo Building json_rewrite_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\json\json_rewrite_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\json_rewrite_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_rewrite_test.obj +json_rewrite_test: json_rewrite_test.exe + echo Running json_rewrite_test + $(OUT_DIR)\json_rewrite_test.exe + +json_test.exe: grpc_test_util + echo Building json_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\json\json_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\json_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\json_test.obj +json_test: json_test.exe + echo Running json_test + $(OUT_DIR)\json_test.exe + +lame_client_test.exe: grpc_test_util + echo Building lame_client_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\lame_client_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\lame_client_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\lame_client_test.obj +lame_client_test: lame_client_test.exe + echo Running lame_client_test + $(OUT_DIR)\lame_client_test.exe + +low_level_ping_pong_benchmark.exe: grpc_test_util + echo Building low_level_ping_pong_benchmark + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\network_benchmarks\low_level_ping_pong.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\low_level_ping_pong_benchmark.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\low_level_ping_pong.obj +low_level_ping_pong_benchmark: low_level_ping_pong_benchmark.exe + echo Running low_level_ping_pong_benchmark + $(OUT_DIR)\low_level_ping_pong_benchmark.exe + +message_compress_test.exe: grpc_test_util + echo Building message_compress_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\compression\message_compress_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\message_compress_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\message_compress_test.obj +message_compress_test: message_compress_test.exe + echo Running message_compress_test + $(OUT_DIR)\message_compress_test.exe + +metadata_buffer_test.exe: grpc_test_util + echo Building metadata_buffer_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\channel\metadata_buffer_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\metadata_buffer_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\metadata_buffer_test.obj +metadata_buffer_test: metadata_buffer_test.exe + echo Running metadata_buffer_test + $(OUT_DIR)\metadata_buffer_test.exe + +multi_init_test.exe: grpc_test_util + echo Building multi_init_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\surface\multi_init_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\multi_init_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multi_init_test.obj +multi_init_test: multi_init_test.exe + echo Running multi_init_test + $(OUT_DIR)\multi_init_test.exe + +murmur_hash_test.exe: grpc_test_util + echo Building murmur_hash_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\murmur_hash_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\murmur_hash_test.exe" Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\murmur_hash_test.obj +murmur_hash_test: murmur_hash_test.exe + echo Running murmur_hash_test + $(OUT_DIR)\murmur_hash_test.exe + +no_server_test.exe: grpc_test_util + echo Building no_server_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\end2end\no_server_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\no_server_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\no_server_test.obj +no_server_test: no_server_test.exe + echo Running no_server_test + $(OUT_DIR)\no_server_test.exe + +poll_kick_posix_test.exe: grpc_test_util + echo Building poll_kick_posix_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\poll_kick_posix_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\poll_kick_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\poll_kick_posix_test.obj +poll_kick_posix_test: poll_kick_posix_test.exe + echo Running poll_kick_posix_test + $(OUT_DIR)\poll_kick_posix_test.exe + +resolve_address_test.exe: grpc_test_util + echo Building resolve_address_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\resolve_address_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\resolve_address_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\resolve_address_test.obj +resolve_address_test: resolve_address_test.exe + echo Running resolve_address_test + $(OUT_DIR)\resolve_address_test.exe + +secure_endpoint_test.exe: grpc_test_util + echo Building secure_endpoint_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\security\secure_endpoint_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\secure_endpoint_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\secure_endpoint_test.obj +secure_endpoint_test: secure_endpoint_test.exe + echo Running secure_endpoint_test + $(OUT_DIR)\secure_endpoint_test.exe + +sockaddr_utils_test.exe: grpc_test_util + echo Building sockaddr_utils_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\sockaddr_utils_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\sockaddr_utils_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\sockaddr_utils_test.obj +sockaddr_utils_test: sockaddr_utils_test.exe + echo Running sockaddr_utils_test + $(OUT_DIR)\sockaddr_utils_test.exe + +tcp_client_posix_test.exe: grpc_test_util + echo Building tcp_client_posix_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\tcp_client_posix_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\tcp_client_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\tcp_client_posix_test.obj +tcp_client_posix_test: tcp_client_posix_test.exe + echo Running tcp_client_posix_test + $(OUT_DIR)\tcp_client_posix_test.exe + +tcp_posix_test.exe: grpc_test_util + echo Building tcp_posix_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\tcp_posix_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\tcp_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\tcp_posix_test.obj +tcp_posix_test: tcp_posix_test.exe + echo Running tcp_posix_test + $(OUT_DIR)\tcp_posix_test.exe + +tcp_server_posix_test.exe: grpc_test_util + echo Building tcp_server_posix_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\tcp_server_posix_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\tcp_server_posix_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\tcp_server_posix_test.obj +tcp_server_posix_test: tcp_server_posix_test.exe + echo Running tcp_server_posix_test + $(OUT_DIR)\tcp_server_posix_test.exe + +time_averaged_stats_test.exe: grpc_test_util + echo Building time_averaged_stats_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\iomgr\time_averaged_stats_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\time_averaged_stats_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\time_averaged_stats_test.obj +time_averaged_stats_test: time_averaged_stats_test.exe + echo Running time_averaged_stats_test + $(OUT_DIR)\time_averaged_stats_test.exe + +time_test.exe: grpc_test_util + echo Building time_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\support\time_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\time_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\time_test.obj +time_test: time_test.exe + echo Running time_test + $(OUT_DIR)\time_test.exe + +timeout_encoding_test.exe: grpc_test_util + echo Building timeout_encoding_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\chttp2\timeout_encoding_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\timeout_encoding_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\timeout_encoding_test.obj +timeout_encoding_test: timeout_encoding_test.exe + echo Running timeout_encoding_test + $(OUT_DIR)\timeout_encoding_test.exe + +transport_metadata_test.exe: grpc_test_util + echo Building transport_metadata_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\transport\metadata_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\transport_metadata_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\metadata_test.obj +transport_metadata_test: transport_metadata_test.exe + echo Running transport_metadata_test + $(OUT_DIR)\transport_metadata_test.exe + +transport_security_test.exe: grpc_test_util + echo Building transport_security_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\tsi\transport_security_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\transport_security_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\transport_security_test.obj +transport_security_test: transport_security_test.exe + echo Running transport_security_test + $(OUT_DIR)\transport_security_test.exe + diff --git a/vsprojects/vs2010/build_openssl_x86.bat b/vsprojects/vs2010/build_openssl_x86.bat new file mode 100644 index 0000000000..9f7a01324f --- /dev/null +++ b/vsprojects/vs2010/build_openssl_x86.bat @@ -0,0 +1,8 @@ +@echo Building OpenSSL 32bits using Visual Studio 2010. + +@call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" x86 + +cd ..\..\third_party\openssl +nmake /F ..\..\vsprojects\third_party\openssl\OpenSSL.mak init out32\ssleay32.lib out32\libeay32.lib + +pause diff --git a/vsprojects/vs2010/global.props b/vsprojects/vs2010/global.props new file mode 100644 index 0000000000..ae44e18d4e --- /dev/null +++ b/vsprojects/vs2010/global.props @@ -0,0 +1,14 @@ +<?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>$(SolutionDir)\..\..;$(SolutionDir)\..\..\include;$(SolutionDir)\..\..\third_party\zlib;$(SolutionDir)\..\third_party;$(SolutionDir)\..\..\third_party\openssl\inc32;$(SolutionDir)\..\..\third_party\protobuf\src</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project>
\ No newline at end of file diff --git a/vsprojects/vs2013/gpr_shared.vcxproj b/vsprojects/vs2010/gpr.vcxproj index 892490e324..d23124c86c 100644 --- a/vsprojects/vs2013/gpr_shared.vcxproj +++ b/vsprojects/vs2010/gpr.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -11,20 +11,18 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}</ProjectGuid> + <ProjectGuid>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</ProjectGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> + <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> <CharacterSet>Unicode</CharacterSet> <IntDir>$(Configuration)\$(ProjectName)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> + <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> <IntDir>$(Configuration)\$(ProjectName)\</IntDir> @@ -85,6 +83,7 @@ <ClInclude Include="..\..\include\grpc\support\atm_win32.h" /> <ClInclude Include="..\..\include\grpc\support\cancellable_platform.h" /> <ClInclude Include="..\..\include\grpc\support\cmdline.h" /> + <ClInclude Include="..\..\include\grpc\support\cpu.h" /> <ClInclude Include="..\..\include\grpc\support\histogram.h" /> <ClInclude Include="..\..\include\grpc\support\host_port.h" /> <ClInclude Include="..\..\include\grpc\support\log.h" /> @@ -115,6 +114,8 @@ </ClCompile> <ClCompile Include="..\..\src\core\support\cmdline.c"> </ClCompile> + <ClCompile Include="..\..\src\core\support\cpu_iphone.c"> + </ClCompile> <ClCompile Include="..\..\src\core\support\cpu_linux.c"> </ClCompile> <ClCompile Include="..\..\src\core\support\cpu_posix.c"> @@ -165,6 +166,8 @@ </ClCompile> <ClCompile Include="..\..\src\core\support\sync_win32.c"> </ClCompile> + <ClCompile Include="..\..\src\core\support\thd.c"> + </ClCompile> <ClCompile Include="..\..\src\core\support\thd_posix.c"> </ClCompile> <ClCompile Include="..\..\src\core\support\thd_win32.c"> diff --git a/vsprojects/vs2013/gpr_shared.vcxproj.filters b/vsprojects/vs2010/gpr.vcxproj.filters index 9b78c3a390..1f8794441b 100644 --- a/vsprojects/vs2013/gpr_shared.vcxproj.filters +++ b/vsprojects/vs2010/gpr.vcxproj.filters @@ -10,6 +10,9 @@ <ClCompile Include="..\..\src\core\support\cmdline.c"> <Filter>src\core\support</Filter> </ClCompile> + <ClCompile Include="..\..\src\core\support\cpu_iphone.c"> + <Filter>src\core\support</Filter> + </ClCompile> <ClCompile Include="..\..\src\core\support\cpu_linux.c"> <Filter>src\core\support</Filter> </ClCompile> @@ -85,6 +88,9 @@ <ClCompile Include="..\..\src\core\support\sync_win32.c"> <Filter>src\core\support</Filter> </ClCompile> + <ClCompile Include="..\..\src\core\support\thd.c"> + <Filter>src\core\support</Filter> + </ClCompile> <ClCompile Include="..\..\src\core\support\thd_posix.c"> <Filter>src\core\support</Filter> </ClCompile> @@ -123,6 +129,9 @@ <ClInclude Include="..\..\include\grpc\support\cmdline.h"> <Filter>include\grpc\support</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc\support\cpu.h"> + <Filter>include\grpc\support</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc\support\histogram.h"> <Filter>include\grpc\support</Filter> </ClInclude> diff --git a/vsprojects/vs2010/gpr_test_util.vcxproj b/vsprojects/vs2010/gpr_test_util.vcxproj new file mode 100644 index 0000000000..0568fcf719 --- /dev/null +++ b/vsprojects/vs2010/gpr_test_util.vcxproj @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>gpr_test_util</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>gpr_test_util</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\..\test\core\util\test_config.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\test\core\util\test_config.c"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/vsprojects/vs2010/grpc++.vcxproj b/vsprojects/vs2010/grpc++.vcxproj new file mode 100644 index 0000000000..003355eabf --- /dev/null +++ b/vsprojects/vs2010/grpc++.vcxproj @@ -0,0 +1,185 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>grpc++</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>grpc++</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\..\include\grpc++\async_generic_service.h" /> + <ClInclude Include="..\..\include\grpc++\async_unary_call.h" /> + <ClInclude Include="..\..\include\grpc++\byte_buffer.h" /> + <ClInclude Include="..\..\include\grpc++\channel_arguments.h" /> + <ClInclude Include="..\..\include\grpc++\channel_interface.h" /> + <ClInclude Include="..\..\include\grpc++\client_context.h" /> + <ClInclude Include="..\..\include\grpc++\completion_queue.h" /> + <ClInclude Include="..\..\include\grpc++\config.h" /> + <ClInclude Include="..\..\include\grpc++\create_channel.h" /> + <ClInclude Include="..\..\include\grpc++\credentials.h" /> + <ClInclude Include="..\..\include\grpc++\generic_stub.h" /> + <ClInclude Include="..\..\include\grpc++\impl\call.h" /> + <ClInclude Include="..\..\include\grpc++\impl\client_unary_call.h" /> + <ClInclude Include="..\..\include\grpc++\impl\internal_stub.h" /> + <ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" /> + <ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" /> + <ClInclude Include="..\..\include\grpc++\impl\service_type.h" /> + <ClInclude Include="..\..\include\grpc++\impl\sync.h" /> + <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" /> + <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" /> + <ClInclude Include="..\..\include\grpc++\impl\thd.h" /> + <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" /> + <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" /> + <ClInclude Include="..\..\include\grpc++\server.h" /> + <ClInclude Include="..\..\include\grpc++\server_builder.h" /> + <ClInclude Include="..\..\include\grpc++\server_context.h" /> + <ClInclude Include="..\..\include\grpc++\server_credentials.h" /> + <ClInclude Include="..\..\include\grpc++\slice.h" /> + <ClInclude Include="..\..\include\grpc++\status.h" /> + <ClInclude Include="..\..\include\grpc++\status_code_enum.h" /> + <ClInclude Include="..\..\include\grpc++\stream.h" /> + <ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\src\cpp\client\secure_credentials.h" /> + <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" /> + <ClInclude Include="..\..\src\cpp\client\channel.h" /> + <ClInclude Include="..\..\src\cpp\proto\proto_utils.h" /> + <ClInclude Include="..\..\src\cpp\server\thread_pool.h" /> + <ClInclude Include="..\..\src\cpp\util\time.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\cpp\client\secure_credentials.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\secure_server_credentials.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\channel.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\channel_arguments.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\client_context.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\client_unary_call.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\create_channel.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\credentials.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\generic_stub.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\internal_stub.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\common\call.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\common\completion_queue.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\common\rpc_method.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\proto\proto_utils.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server_builder.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server_context.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server_credentials.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\thread_pool.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\slice.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\status.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\time.cc"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + <ProjectReference Include="grpc.vcxproj"> + <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/vsprojects/vs2010/grpc++.vcxproj.filters b/vsprojects/vs2010/grpc++.vcxproj.filters new file mode 100644 index 0000000000..6466a0fa26 --- /dev/null +++ b/vsprojects/vs2010/grpc++.vcxproj.filters @@ -0,0 +1,235 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="..\..\src\cpp\client\secure_credentials.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\secure_server_credentials.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\channel.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\channel_arguments.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\client_context.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\client_unary_call.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\create_channel.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\credentials.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\generic_stub.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\client\internal_stub.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\common\call.cc"> + <Filter>src\cpp\common</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\common\completion_queue.cc"> + <Filter>src\cpp\common</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\common\rpc_method.cc"> + <Filter>src\cpp\common</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\proto\proto_utils.cc"> + <Filter>src\cpp\proto</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server_builder.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server_context.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\server_credentials.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\server\thread_pool.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc"> + <Filter>src\cpp\util</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\slice.cc"> + <Filter>src\cpp\util</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\status.cc"> + <Filter>src\cpp\util</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\time.cc"> + <Filter>src\cpp\util</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\grpc++\async_generic_service.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\async_unary_call.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\byte_buffer.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\channel_arguments.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\channel_interface.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\client_context.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\completion_queue.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\config.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\create_channel.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\credentials.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\generic_stub.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\call.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\client_unary_call.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\internal_stub.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\rpc_method.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\service_type.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\sync.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\thd.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\server.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\server_builder.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\server_context.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\server_credentials.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\slice.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\status.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\status_code_enum.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\stream.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\thread_pool_interface.h"> + <Filter>include\grpc++</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\src\cpp\client\secure_credentials.h"> + <Filter>src\cpp\client</Filter> + </ClInclude> + <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h"> + <Filter>src\cpp\server</Filter> + </ClInclude> + <ClInclude Include="..\..\src\cpp\client\channel.h"> + <Filter>src\cpp\client</Filter> + </ClInclude> + <ClInclude Include="..\..\src\cpp\proto\proto_utils.h"> + <Filter>src\cpp\proto</Filter> + </ClInclude> + <ClInclude Include="..\..\src\cpp\server\thread_pool.h"> + <Filter>src\cpp\server</Filter> + </ClInclude> + <ClInclude Include="..\..\src\cpp\util\time.h"> + <Filter>src\cpp\util</Filter> + </ClInclude> + </ItemGroup> + + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{82445414-24cd-8198-1fe1-4267c3f3df00}</UniqueIdentifier> + </Filter> + <Filter Include="include\grpc++"> + <UniqueIdentifier>{784a0281-f547-aeb0-9f55-b26b7de9c769}</UniqueIdentifier> + </Filter> + <Filter Include="include\grpc++\impl"> + <UniqueIdentifier>{0da8cd95-314f-da1b-5ce7-7791a5be1f1a}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{328ff211-2886-406e-56f9-18ba1686f363}</UniqueIdentifier> + </Filter> + <Filter Include="src\cpp"> + <UniqueIdentifier>{2420a905-e4f1-a5aa-a364-6a112878a39e}</UniqueIdentifier> + </Filter> + <Filter Include="src\cpp\client"> + <UniqueIdentifier>{7febf32a-d7a6-76fa-9e17-f189f591c062}</UniqueIdentifier> + </Filter> + <Filter Include="src\cpp\common"> + <UniqueIdentifier>{2336e396-7e0b-8bf9-3b09-adc6ad1f0e5b}</UniqueIdentifier> + </Filter> + <Filter Include="src\cpp\proto"> + <UniqueIdentifier>{c22e8b9b-d2eb-a2e8-0cb8-3f7e3c902a7b}</UniqueIdentifier> + </Filter> + <Filter Include="src\cpp\server"> + <UniqueIdentifier>{321b0980-74ad-e8ca-f23b-deffa5d6bb8f}</UniqueIdentifier> + </Filter> + <Filter Include="src\cpp\util"> + <UniqueIdentifier>{f842537a-2bf1-1ec3-b495-7d62c64a1c06}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project> + diff --git a/vsprojects/vs2010/grpc.sln b/vsprojects/vs2010/grpc.sln new file mode 100644 index 0000000000..8d1f87789d --- /dev/null +++ b/vsprojects/vs2010/grpc.sln @@ -0,0 +1,97 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr", "gpr.vcxproj", "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_test_util", "gpr_test_util.vcxproj", "{EAB0A629-17A9-44DB-B5FF-E91A721FE037}" + ProjectSection(ProjectDependencies) = postProject + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc", "grpc.vcxproj", "{29D16885-7228-4C31-81ED-5F9187C7F2A9}" + ProjectSection(ProjectDependencies) = postProject + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}" + ProjectSection(ProjectDependencies) = postProject + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_unsecure", "grpc_unsecure.vcxproj", "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}" + ProjectSection(ProjectDependencies) = postProject + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "grpc++.vcxproj", "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}" + ProjectSection(ProjectDependencies) = postProject + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext", "grpc_csharp_ext.vcxproj", "{D64C6D63-4458-4A88-AB38-35678384A7E4}" + ProjectSection(ProjectDependencies) = postProject + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.ActiveCfg = Debug|Win32 + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.Build.0 = Debug|Win32 + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.ActiveCfg = Release|Win32 + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.Build.0 = Release|Win32 + {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.ActiveCfg = Debug|Win32 + {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.Build.0 = Debug|Win32 + {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.ActiveCfg = Release|Win32 + {EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.Build.0 = Release|Win32 + {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.ActiveCfg = Debug|Win32 + {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.Build.0 = Debug|Win32 + {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.ActiveCfg = Release|Win32 + {29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.Build.0 = Release|Win32 + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32 + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.Build.0 = Debug|Win32 + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32 + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.Build.0 = Release|Win32 + {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.ActiveCfg = Debug|Win32 + {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.Build.0 = Debug|Win32 + {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.ActiveCfg = Release|Win32 + {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.Build.0 = Release|Win32 + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.Build.0 = Debug|Win32 + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.ActiveCfg = Release|Win32 + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.Build.0 = Release|Win32 + {D64C6D63-4458-4A88-AB38-35678384A7E4}.Debug|Win32.ActiveCfg = Debug|Win32 + {D64C6D63-4458-4A88-AB38-35678384A7E4}.Debug|Win32.Build.0 = Debug|Win32 + {D64C6D63-4458-4A88-AB38-35678384A7E4}.Release|Win32.ActiveCfg = Release|Win32 + {D64C6D63-4458-4A88-AB38-35678384A7E4}.Release|Win32.Build.0 = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32 + {8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.ActiveCfg = Debug|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Debug|Win32.Build.0 = Debug|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.ActiveCfg = Release|Win32 + {3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}.Release|Win32.Build.0 = Release|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.ActiveCfg = Debug|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Debug|Win32.Build.0 = Debug|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.ActiveCfg = Release|Win32 + {F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}.Release|Win32.Build.0 = Release|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.ActiveCfg = Debug|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Debug|Win32.Build.0 = Debug|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.ActiveCfg = Release|Win32 + {C26D04A8-37C6-44C7-B458-906C9FCE928C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/vsprojects/vs2013/grpc_shared.vcxproj b/vsprojects/vs2010/grpc.vcxproj index f5575dc3f1..203ca347d3 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj +++ b/vsprojects/vs2010/grpc.vcxproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> <Configuration>Debug</Configuration> @@ -11,20 +11,18 @@ </ProjectConfiguration> </ItemGroup> <PropertyGroup Label="Globals"> - <ProjectGuid>{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}</ProjectGuid> + <ProjectGuid>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</ProjectGuid> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> + <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> <CharacterSet>Unicode</CharacterSet> <IntDir>$(Configuration)\$(ProjectName)\</IntDir> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> + <ConfigurationType>StaticLibrary</ConfigurationType> <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v120</PlatformToolset> <WholeProgramOptimization>true</WholeProgramOptimization> <CharacterSet>Unicode</CharacterSet> <IntDir>$(Configuration)\$(ProjectName)\</IntDir> @@ -35,14 +33,10 @@ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="global.props" /> - <Import Project="ssl.props" /> - <Import Project="winsock.props" /> </ImportGroup> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="global.props" /> - <Import Project="ssl.props" /> - <Import Project="winsock.props" /> </ImportGroup> <PropertyGroup Label="UserMacros" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> @@ -86,6 +80,7 @@ <ClInclude Include="..\..\include\grpc\byte_buffer.h" /> <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" /> <ClInclude Include="..\..\include\grpc\grpc.h" /> + <ClInclude Include="..\..\include\grpc\grpc_http.h" /> <ClInclude Include="..\..\include\grpc\status.h" /> </ItemGroup> <ItemGroup> @@ -97,6 +92,7 @@ <ClInclude Include="..\..\src\core\security\base64.h" /> <ClInclude Include="..\..\src\core\security\credentials.h" /> <ClInclude Include="..\..\src\core\security\json_token.h" /> + <ClInclude Include="..\..\src\core\security\secure_endpoint.h" /> <ClInclude Include="..\..\src\core\security\secure_transport_setup.h" /> <ClInclude Include="..\..\src\core\security\security_context.h" /> <ClInclude Include="..\..\src\core\tsi\fake_transport_security.h" /> @@ -167,6 +163,7 @@ <ClInclude Include="..\..\src\core\surface\init.h" /> <ClInclude Include="..\..\src\core\surface\server.h" /> <ClInclude Include="..\..\src\core\surface\surface_trace.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\frame.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" /> @@ -359,6 +356,8 @@ </ClCompile> <ClCompile Include="..\..\src\core\surface\call_details.c"> </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + </ClCompile> <ClCompile Include="..\..\src\core\surface\channel.c"> </ClCompile> <ClCompile Include="..\..\src\core\surface\channel_create.c"> @@ -428,12 +427,8 @@ <ProjectReference Include="gpr.vcxproj"> <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> </ProjectReference> - <ProjectReference Include="third_party\zlibvc.vcxproj"> - <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project> - </ProjectReference> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> </Project> - diff --git a/vsprojects/vs2013/grpc_shared.vcxproj.filters b/vsprojects/vs2010/grpc.vcxproj.filters index af38d8de35..20dbe8c444 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj.filters +++ b/vsprojects/vs2010/grpc.vcxproj.filters @@ -253,6 +253,9 @@ <ClCompile Include="..\..\src\core\surface\call_details.c"> <Filter>src\core\surface</Filter> </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + <Filter>src\core\surface</Filter> + </ClCompile> <ClCompile Include="..\..\src\core\surface\channel.c"> <Filter>src\core\surface</Filter> </ClCompile> @@ -363,6 +366,9 @@ <ClInclude Include="..\..\include\grpc\grpc.h"> <Filter>include\grpc</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc\grpc_http.h"> + <Filter>include\grpc</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc\status.h"> <Filter>include\grpc</Filter> </ClInclude> @@ -392,6 +398,9 @@ <ClInclude Include="..\..\src\core\security\json_token.h"> <Filter>src\core\security</Filter> </ClInclude> + <ClInclude Include="..\..\src\core\security\secure_endpoint.h"> + <Filter>src\core\security</Filter> + </ClInclude> <ClInclude Include="..\..\src\core\security\secure_transport_setup.h"> <Filter>src\core\security</Filter> </ClInclude> @@ -602,6 +611,9 @@ <ClInclude Include="..\..\src\core\surface\surface_trace.h"> <Filter>src\core\surface</Filter> </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h"> <Filter>src\core\transport\chttp2</Filter> </ClInclude> diff --git a/vsprojects/vs2010/grpc_csharp_ext.vcxproj b/vsprojects/vs2010/grpc_csharp_ext.vcxproj new file mode 100644 index 0000000000..a507a9b714 --- /dev/null +++ b/vsprojects/vs2010/grpc_csharp_ext.vcxproj @@ -0,0 +1,94 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D64C6D63-4458-4A88-AB38-35678384A7E4}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>grpc_csharp_ext</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>grpc_csharp_ext</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\src\csharp\ext\grpc_csharp_ext.c"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + <ProjectReference Include="grpc.vcxproj"> + <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> + diff --git a/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj b/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj new file mode 100644 index 0000000000..b17f927de4 --- /dev/null +++ b/vsprojects/vs2010/grpc_csharp_ext_shared.vcxproj @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C26D04A8-37C6-44C7-B458-906C9FCE928C}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + <Import Project="winsock.props" /> + <Import Project="ssl.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + <Import Project="winsock.props" /> + <Import Project="ssl.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>grpc_csharp_ext</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>grpc_csharp_ext</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\src\csharp\ext\grpc_csharp_ext.c"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + <ProjectReference Include="grpc.vcxproj"> + <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> + diff --git a/vsprojects/vs2010/grpc_test_util.vcxproj b/vsprojects/vs2010/grpc_test_util.vcxproj new file mode 100644 index 0000000000..967543f78a --- /dev/null +++ b/vsprojects/vs2010/grpc_test_util.vcxproj @@ -0,0 +1,116 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>grpc_test_util</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>grpc_test_util</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\test\core\end2end\cq_verifier.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\end2end\data\server1_cert.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\end2end\data\server1_key.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\end2end\data\test_root_cert.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\iomgr\endpoint_tests.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\statistics\census_log_tests.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\transport\transport_end2end_tests.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\util\grpc_profiler.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\util\parse_hexstring.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\util\port_posix.c"> + </ClCompile> + <ClCompile Include="..\..\test\core\util\slice_splitter.c"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + <ProjectReference Include="gpr_test_util.vcxproj"> + <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project> + </ProjectReference> + <ProjectReference Include="grpc.vcxproj"> + <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/vsprojects/vs2010/grpc_unsecure.vcxproj b/vsprojects/vs2010/grpc_unsecure.vcxproj new file mode 100644 index 0000000000..1558d72514 --- /dev/null +++ b/vsprojects/vs2010/grpc_unsecure.vcxproj @@ -0,0 +1,378 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <IntDir>$(Configuration)\$(ProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="global.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>grpc_unsecure</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>grpc_unsecure</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\..\include\grpc\byte_buffer.h" /> + <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" /> + <ClInclude Include="..\..\include\grpc\grpc.h" /> + <ClInclude Include="..\..\include\grpc\grpc_http.h" /> + <ClInclude Include="..\..\include\grpc\status.h" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\src\core\channel\census_filter.h" /> + <ClInclude Include="..\..\src\core\channel\channel_args.h" /> + <ClInclude Include="..\..\src\core\channel\channel_stack.h" /> + <ClInclude Include="..\..\src\core\channel\child_channel.h" /> + <ClInclude Include="..\..\src\core\channel\client_channel.h" /> + <ClInclude Include="..\..\src\core\channel\client_setup.h" /> + <ClInclude Include="..\..\src\core\channel\connected_channel.h" /> + <ClInclude Include="..\..\src\core\channel\http_client_filter.h" /> + <ClInclude Include="..\..\src\core\channel\http_filter.h" /> + <ClInclude Include="..\..\src\core\channel\http_server_filter.h" /> + <ClInclude Include="..\..\src\core\channel\metadata_buffer.h" /> + <ClInclude Include="..\..\src\core\channel\noop_filter.h" /> + <ClInclude Include="..\..\src\core\compression\algorithm.h" /> + <ClInclude Include="..\..\src\core\compression\message_compress.h" /> + <ClInclude Include="..\..\src\core\debug\trace.h" /> + <ClInclude Include="..\..\src\core\iomgr\alarm.h" /> + <ClInclude Include="..\..\src\core\iomgr\alarm_heap.h" /> + <ClInclude Include="..\..\src\core\iomgr\alarm_internal.h" /> + <ClInclude Include="..\..\src\core\iomgr\endpoint.h" /> + <ClInclude Include="..\..\src\core\iomgr\endpoint_pair.h" /> + <ClInclude Include="..\..\src\core\iomgr\fd_posix.h" /> + <ClInclude Include="..\..\src\core\iomgr\iocp_windows.h" /> + <ClInclude Include="..\..\src\core\iomgr\iomgr.h" /> + <ClInclude Include="..\..\src\core\iomgr\iomgr_internal.h" /> + <ClInclude Include="..\..\src\core\iomgr\iomgr_posix.h" /> + <ClInclude Include="..\..\src\core\iomgr\pollset.h" /> + <ClInclude Include="..\..\src\core\iomgr\pollset_kick.h" /> + <ClInclude Include="..\..\src\core\iomgr\pollset_kick_posix.h" /> + <ClInclude Include="..\..\src\core\iomgr\pollset_kick_windows.h" /> + <ClInclude Include="..\..\src\core\iomgr\pollset_posix.h" /> + <ClInclude Include="..\..\src\core\iomgr\pollset_windows.h" /> + <ClInclude Include="..\..\src\core\iomgr\resolve_address.h" /> + <ClInclude Include="..\..\src\core\iomgr\sockaddr.h" /> + <ClInclude Include="..\..\src\core\iomgr\sockaddr_posix.h" /> + <ClInclude Include="..\..\src\core\iomgr\sockaddr_utils.h" /> + <ClInclude Include="..\..\src\core\iomgr\sockaddr_win32.h" /> + <ClInclude Include="..\..\src\core\iomgr\socket_utils_posix.h" /> + <ClInclude Include="..\..\src\core\iomgr\socket_windows.h" /> + <ClInclude Include="..\..\src\core\iomgr\tcp_client.h" /> + <ClInclude Include="..\..\src\core\iomgr\tcp_posix.h" /> + <ClInclude Include="..\..\src\core\iomgr\tcp_server.h" /> + <ClInclude Include="..\..\src\core\iomgr\tcp_windows.h" /> + <ClInclude Include="..\..\src\core\iomgr\time_averaged_stats.h" /> + <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_pipe.h" /> + <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_posix.h" /> + <ClInclude Include="..\..\src\core\json\json.h" /> + <ClInclude Include="..\..\src\core\json\json_common.h" /> + <ClInclude Include="..\..\src\core\json\json_reader.h" /> + <ClInclude Include="..\..\src\core\json\json_writer.h" /> + <ClInclude Include="..\..\src\core\statistics\census_interface.h" /> + <ClInclude Include="..\..\src\core\statistics\census_log.h" /> + <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h" /> + <ClInclude Include="..\..\src\core\statistics\census_tracing.h" /> + <ClInclude Include="..\..\src\core\statistics\hash_table.h" /> + <ClInclude Include="..\..\src\core\statistics\window_stats.h" /> + <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h" /> + <ClInclude Include="..\..\src\core\surface\call.h" /> + <ClInclude Include="..\..\src\core\surface\channel.h" /> + <ClInclude Include="..\..\src\core\surface\client.h" /> + <ClInclude Include="..\..\src\core\surface\completion_queue.h" /> + <ClInclude Include="..\..\src\core\surface\event_string.h" /> + <ClInclude Include="..\..\src\core\surface\init.h" /> + <ClInclude Include="..\..\src\core\surface\server.h" /> + <ClInclude Include="..\..\src\core\surface\surface_trace.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\frame.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_goaway.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_ping.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_rst_stream.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_settings.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_window_update.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\hpack_parser.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\hpack_table.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\http2_errors.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\huffsyms.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\status_conversion.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\stream_encoder.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\stream_map.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\timeout_encoding.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\varint.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2_transport.h" /> + <ClInclude Include="..\..\src\core\transport\metadata.h" /> + <ClInclude Include="..\..\src\core\transport\stream_op.h" /> + <ClInclude Include="..\..\src\core\transport\transport.h" /> + <ClInclude Include="..\..\src\core\transport\transport_impl.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\core\surface\init_unsecure.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\call_op_string.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\census_filter.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\channel_args.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\channel_stack.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\child_channel.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\client_channel.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\client_setup.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\connected_channel.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\http_client_filter.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\http_filter.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\http_server_filter.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\metadata_buffer.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\noop_filter.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\compression\algorithm.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\compression\message_compress.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\debug\trace.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\alarm.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\alarm_heap.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\endpoint.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\endpoint_pair_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\fd_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iocp_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iomgr.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iomgr_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iomgr_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_kick.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_epoll.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\resolve_address_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\resolve_address_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\sockaddr_utils.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_utils_common_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_utils_linux.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_utils_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_client_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_client_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_server_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_server_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_windows.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\time_averaged_stats.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_eventfd.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_nospecial.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_pipe.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_posix.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json_reader.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json_string.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json_writer.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_init.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_log.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_tracing.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\hash_table.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\window_stats.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\byte_buffer.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\byte_buffer_queue.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\byte_buffer_reader.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\call.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_details.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\channel.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\channel_create.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\client.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\completion_queue.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\event_string.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\init.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\lame_client.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\metadata_array.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\server.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\server_chttp2.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\server_create.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\surface_trace.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\alpn.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\bin_encoder.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_data.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_goaway.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_ping.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_rst_stream.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_settings.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_window_update.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\hpack_parser.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\hpack_table.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\huffsyms.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\status_conversion.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\stream_encoder.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\stream_map.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\timeout_encoding.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\varint.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2_transport.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\metadata.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\stream_op.c"> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\transport.c"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/vsprojects/vs2010/grpc_unsecure.vcxproj.filters b/vsprojects/vs2010/grpc_unsecure.vcxproj.filters new file mode 100644 index 0000000000..4b758d6113 --- /dev/null +++ b/vsprojects/vs2010/grpc_unsecure.vcxproj.filters @@ -0,0 +1,619 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="..\..\src\core\surface\init_unsecure.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\call_op_string.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\census_filter.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\channel_args.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\channel_stack.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\child_channel.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\client_channel.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\client_setup.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\connected_channel.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\http_client_filter.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\http_filter.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\http_server_filter.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\metadata_buffer.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\channel\noop_filter.c"> + <Filter>src\core\channel</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\compression\algorithm.c"> + <Filter>src\core\compression</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\compression\message_compress.c"> + <Filter>src\core\compression</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\debug\trace.c"> + <Filter>src\core\debug</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\alarm.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\alarm_heap.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\endpoint.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\endpoint_pair_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\fd_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iocp_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iomgr.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iomgr_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\iomgr_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_kick.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_epoll.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_multipoller_with_poll_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\pollset_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\resolve_address_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\resolve_address_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\sockaddr_utils.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_utils_common_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_utils_linux.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_utils_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\socket_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_client_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_client_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_server_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_server_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\tcp_windows.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\time_averaged_stats.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_eventfd.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_nospecial.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_pipe.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\iomgr\wakeup_fd_posix.c"> + <Filter>src\core\iomgr</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json.c"> + <Filter>src\core\json</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json_reader.c"> + <Filter>src\core\json</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json_string.c"> + <Filter>src\core\json</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\json\json_writer.c"> + <Filter>src\core\json</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_init.c"> + <Filter>src\core\statistics</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_log.c"> + <Filter>src\core\statistics</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c"> + <Filter>src\core\statistics</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\census_tracing.c"> + <Filter>src\core\statistics</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\hash_table.c"> + <Filter>src\core\statistics</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\statistics\window_stats.c"> + <Filter>src\core\statistics</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\byte_buffer.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\byte_buffer_queue.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\byte_buffer_reader.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\call.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_details.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\channel.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\channel_create.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\client.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\completion_queue.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\event_string.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\init.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\lame_client.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\metadata_array.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\server.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\server_chttp2.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\server_create.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\surface\surface_trace.c"> + <Filter>src\core\surface</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\alpn.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\bin_encoder.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_data.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_goaway.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_ping.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_rst_stream.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_settings.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\frame_window_update.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\hpack_parser.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\hpack_table.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\huffsyms.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\status_conversion.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\stream_encoder.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\stream_map.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\timeout_encoding.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2\varint.c"> + <Filter>src\core\transport\chttp2</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\chttp2_transport.c"> + <Filter>src\core\transport</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\metadata.c"> + <Filter>src\core\transport</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\stream_op.c"> + <Filter>src\core\transport</Filter> + </ClCompile> + <ClCompile Include="..\..\src\core\transport\transport.c"> + <Filter>src\core\transport</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\grpc\byte_buffer.h"> + <Filter>include\grpc</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h"> + <Filter>include\grpc</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc\grpc.h"> + <Filter>include\grpc</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc\grpc_http.h"> + <Filter>include\grpc</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc\status.h"> + <Filter>include\grpc</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\src\core\channel\census_filter.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\channel_args.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\channel_stack.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\child_channel.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\client_channel.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\client_setup.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\connected_channel.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\http_client_filter.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\http_filter.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\http_server_filter.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\metadata_buffer.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\channel\noop_filter.h"> + <Filter>src\core\channel</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\compression\algorithm.h"> + <Filter>src\core\compression</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\compression\message_compress.h"> + <Filter>src\core\compression</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\debug\trace.h"> + <Filter>src\core\debug</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\alarm.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\alarm_heap.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\alarm_internal.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\endpoint.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\endpoint_pair.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\fd_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\iocp_windows.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\iomgr.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\iomgr_internal.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\iomgr_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\pollset.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\pollset_kick.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\pollset_kick_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\pollset_kick_windows.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\pollset_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\pollset_windows.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\resolve_address.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\sockaddr.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\sockaddr_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\sockaddr_utils.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\sockaddr_win32.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\socket_utils_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\socket_windows.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\tcp_client.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\tcp_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\tcp_server.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\tcp_windows.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\time_averaged_stats.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_pipe.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\iomgr\wakeup_fd_posix.h"> + <Filter>src\core\iomgr</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\json\json.h"> + <Filter>src\core\json</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\json\json_common.h"> + <Filter>src\core\json</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\json\json_reader.h"> + <Filter>src\core\json</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\json\json_writer.h"> + <Filter>src\core\json</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\statistics\census_interface.h"> + <Filter>src\core\statistics</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\statistics\census_log.h"> + <Filter>src\core\statistics</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h"> + <Filter>src\core\statistics</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\statistics\census_tracing.h"> + <Filter>src\core\statistics</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\statistics\hash_table.h"> + <Filter>src\core\statistics</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\statistics\window_stats.h"> + <Filter>src\core\statistics</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\call.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\channel.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\client.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\completion_queue.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\event_string.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\init.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\server.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\surface\surface_trace.h"> + <Filter>src\core\surface</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\frame.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_goaway.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_ping.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_rst_stream.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_settings.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\frame_window_update.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\hpack_parser.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\hpack_table.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\http2_errors.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\huffsyms.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\status_conversion.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\stream_encoder.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\stream_map.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\timeout_encoding.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\varint.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2_transport.h"> + <Filter>src\core\transport</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\metadata.h"> + <Filter>src\core\transport</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\stream_op.h"> + <Filter>src\core\transport</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\transport.h"> + <Filter>src\core\transport</Filter> + </ClInclude> + <ClInclude Include="..\..\src\core\transport\transport_impl.h"> + <Filter>src\core\transport</Filter> + </ClInclude> + </ItemGroup> + + <ItemGroup> + <Filter Include="include"> + <UniqueIdentifier>{10076c7e-7c8e-8005-0c81-64454af2cbc8}</UniqueIdentifier> + </Filter> + <Filter Include="include\grpc"> + <UniqueIdentifier>{77b9717b-b8d8-dd5f-14bb-a3e96809a70a}</UniqueIdentifier> + </Filter> + <Filter Include="src"> + <UniqueIdentifier>{aaf326a1-c884-46ea-875a-cbbd9983e539}</UniqueIdentifier> + </Filter> + <Filter Include="src\core"> + <UniqueIdentifier>{88491077-386b-2039-d14c-0c40136b5f7a}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\channel"> + <UniqueIdentifier>{cc102c4b-66ff-cf4c-2288-d76327e1a183}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\compression"> + <UniqueIdentifier>{2e3aca1d-223d-10a1-b282-7f9fc68ee6f5}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\debug"> + <UniqueIdentifier>{6d8d5774-7291-554d-fafa-583463cd3fd9}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\iomgr"> + <UniqueIdentifier>{a9df8b24-ecea-ff6d-8999-d8fa54cd70bf}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\json"> + <UniqueIdentifier>{443ffc61-1bea-2477-6e54-1ddf8c139264}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\statistics"> + <UniqueIdentifier>{e084164c-a069-00e3-db35-4e0b1cd6f0b7}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\surface"> + <UniqueIdentifier>{6cd0127e-c24b-d43c-38f5-198db8d4322a}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\transport"> + <UniqueIdentifier>{6687ff98-e36e-c0b1-2756-1bc79edec406}</UniqueIdentifier> + </Filter> + <Filter Include="src\core\transport\chttp2"> + <UniqueIdentifier>{5fcd6206-f774-9ae6-4b85-305d6a723843}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project> + diff --git a/vsprojects/vs2010/ssl.props b/vsprojects/vs2010/ssl.props new file mode 100644 index 0000000000..283bd17817 --- /dev/null +++ b/vsprojects/vs2010/ssl.props @@ -0,0 +1,13 @@ +<?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>
+ <Link>
+ <AdditionalLibraryDirectories>..\..\third_party\openssl\out32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>ssleay32.lib;libeay32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project>
\ No newline at end of file diff --git a/vsprojects/vs2010/third_party/zlibvc.vcxproj b/vsprojects/vs2010/third_party/zlibvc.vcxproj new file mode 100644 index 0000000000..749e3fcafb --- /dev/null +++ b/vsprojects/vs2010/third_party/zlibvc.vcxproj @@ -0,0 +1,188 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <WholeProgramOptimization>true</WholeProgramOptimization> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> + <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest> + <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> + <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest> + <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapi</TargetName> + <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Midl> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MkTypLibCompatible>true</MkTypLibCompatible> + <SuppressStartupBanner>true</SuppressStartupBanner> + <TargetEnvironment>Win32</TargetEnvironment> + <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName> + </Midl> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>..\..\..\third_party\zlib;..\..\..\third_party\zlib\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ExceptionHandling> + </ExceptionHandling> + <BufferSecurityCheck>false</BufferSecurityCheck> + <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <ObjectFileName>$(IntDir)</ObjectFileName> + <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName> + <BrowseInformation> + </BrowseInformation> + <WarningLevel>Level3</WarningLevel> + <SuppressStartupBanner>true</SuppressStartupBanner> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x040c</Culture> + </ResourceCompile> + <Link> + <AdditionalOptions>/MACHINE:I386 /SAFESEH:NO %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>..\..\..\third_party\zlib\contrib\masmx86\match686.obj;..\..\..\third_party\zlib\contrib\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)zlibwapi.dll</OutputFile> + <SuppressStartupBanner>true</SuppressStartupBanner> + <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile> + <GenerateMapFile>true</GenerateMapFile> + <MapFileName>$(OutDir)zlibwapi.map</MapFileName> + <SubSystem>Windows</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary> + </Link> + <PreBuildEvent> + <Command>cd ..\..\..\third_party\zlib\contrib\masmx86 + bld_ml32.bat</Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Midl> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MkTypLibCompatible>true</MkTypLibCompatible> + <SuppressStartupBanner>true</SuppressStartupBanner> + <TargetEnvironment>Win32</TargetEnvironment> + <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName> + </Midl> + <ClCompile> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <AdditionalIncludeDirectories>..\..\..\third_party\zlib;..\..\..\third_party\zlib\contrib\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <ExceptionHandling> + </ExceptionHandling> + <BufferSecurityCheck>false</BufferSecurityCheck> + <FunctionLevelLinking>true</FunctionLevelLinking> + <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile> + <AssemblerOutput>All</AssemblerOutput> + <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation> + <ObjectFileName>$(IntDir)</ObjectFileName> + <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName> + <BrowseInformation> + </BrowseInformation> + <WarningLevel>Level3</WarningLevel> + <SuppressStartupBanner>true</SuppressStartupBanner> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x040c</Culture> + </ResourceCompile> + <Link> + <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions> + <AdditionalDependencies>..\..\..\third_party\zlib\contrib\masmx86\match686.obj;..\..\..\third_party\zlib\contrib\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)zlibwapi.dll</OutputFile> + <SuppressStartupBanner>true</SuppressStartupBanner> + <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> + <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile> + <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile> + <GenerateMapFile>true</GenerateMapFile> + <MapFileName>$(OutDir)zlibwapi.map</MapFileName> + <SubSystem>Windows</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <DataExecutionPrevention> + </DataExecutionPrevention> + <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary> + </Link> + <PreBuildEvent> + <Command>cd ..\..\..\third_party\zlib\contrib\masmx86 + bld_ml32.bat</Command> + </PreBuildEvent> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\..\third_party\zlib\adler32.c" /> + <ClCompile Include="..\..\..\third_party\zlib\compress.c" /> + <ClCompile Include="..\..\..\third_party\zlib\crc32.c" /> + <ClCompile Include="..\..\..\third_party\zlib\deflate.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzclose.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzlib.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzread.c" /> + <ClCompile Include="..\..\..\third_party\zlib\gzwrite.c" /> + <ClCompile Include="..\..\..\third_party\zlib\infback.c" /> + <ClCompile Include="..\..\..\third_party\zlib\inffast.c" /> + <ClCompile Include="..\..\..\third_party\zlib\inflate.c" /> + <ClCompile Include="..\..\..\third_party\zlib\inftrees.c" /> + <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\ioapi.c" /> + <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\iowin32.c" /> + <ClCompile Include="..\..\..\third_party\zlib\trees.c" /> + <ClCompile Include="..\..\..\third_party\zlib\uncompr.c" /> + <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\unzip.c"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\third_party\zlib\contrib\minizip\zip.c"> + <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\..\..\third_party\zlib\zutil.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\..\third_party\zlib\deflate.h" /> + <ClInclude Include="..\..\..\third_party\zlib\infblock.h" /> + <ClInclude Include="..\..\..\third_party\zlib\infcodes.h" /> + <ClInclude Include="..\..\..\third_party\zlib\inffast.h" /> + <ClInclude Include="..\..\..\third_party\zlib\inftrees.h" /> + <ClInclude Include="..\..\..\third_party\zlib\infutil.h" /> + <ClInclude Include="..\..\..\third_party\zlib\zconf.h" /> + <ClInclude Include="..\..\..\third_party\zlib\zlib.h" /> + <ClInclude Include="..\..\..\third_party\zlib\zutil.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/vsprojects/vs2010/winsock.props b/vsprojects/vs2010/winsock.props new file mode 100644 index 0000000000..1e84104911 --- /dev/null +++ b/vsprojects/vs2010/winsock.props @@ -0,0 +1,12 @@ +<?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>
+ <Link>
+ <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup />
+</Project>
\ No newline at end of file diff --git a/vsprojects/vs2013/gpr.vcxproj b/vsprojects/vs2013/gpr.vcxproj index 3d970079a4..e0fa68e035 100644 --- a/vsprojects/vs2013/gpr.vcxproj +++ b/vsprojects/vs2013/gpr.vcxproj @@ -85,6 +85,7 @@ <ClInclude Include="..\..\include\grpc\support\atm_win32.h" /> <ClInclude Include="..\..\include\grpc\support\cancellable_platform.h" /> <ClInclude Include="..\..\include\grpc\support\cmdline.h" /> + <ClInclude Include="..\..\include\grpc\support\cpu.h" /> <ClInclude Include="..\..\include\grpc\support\histogram.h" /> <ClInclude Include="..\..\include\grpc\support\host_port.h" /> <ClInclude Include="..\..\include\grpc\support\log.h" /> @@ -115,6 +116,8 @@ </ClCompile> <ClCompile Include="..\..\src\core\support\cmdline.c"> </ClCompile> + <ClCompile Include="..\..\src\core\support\cpu_iphone.c"> + </ClCompile> <ClCompile Include="..\..\src\core\support\cpu_linux.c"> </ClCompile> <ClCompile Include="..\..\src\core\support\cpu_posix.c"> @@ -165,6 +168,8 @@ </ClCompile> <ClCompile Include="..\..\src\core\support\sync_win32.c"> </ClCompile> + <ClCompile Include="..\..\src\core\support\thd.c"> + </ClCompile> <ClCompile Include="..\..\src\core\support\thd_posix.c"> </ClCompile> <ClCompile Include="..\..\src\core\support\thd_win32.c"> diff --git a/vsprojects/vs2013/gpr.vcxproj.filters b/vsprojects/vs2013/gpr.vcxproj.filters index 9b78c3a390..1f8794441b 100644 --- a/vsprojects/vs2013/gpr.vcxproj.filters +++ b/vsprojects/vs2013/gpr.vcxproj.filters @@ -10,6 +10,9 @@ <ClCompile Include="..\..\src\core\support\cmdline.c"> <Filter>src\core\support</Filter> </ClCompile> + <ClCompile Include="..\..\src\core\support\cpu_iphone.c"> + <Filter>src\core\support</Filter> + </ClCompile> <ClCompile Include="..\..\src\core\support\cpu_linux.c"> <Filter>src\core\support</Filter> </ClCompile> @@ -85,6 +88,9 @@ <ClCompile Include="..\..\src\core\support\sync_win32.c"> <Filter>src\core\support</Filter> </ClCompile> + <ClCompile Include="..\..\src\core\support\thd.c"> + <Filter>src\core\support</Filter> + </ClCompile> <ClCompile Include="..\..\src\core\support\thd_posix.c"> <Filter>src\core\support</Filter> </ClCompile> @@ -123,6 +129,9 @@ <ClInclude Include="..\..\include\grpc\support\cmdline.h"> <Filter>include\grpc\support</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc\support\cpu.h"> + <Filter>include\grpc\support</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc\support\histogram.h"> <Filter>include\grpc\support</Filter> </ClInclude> diff --git a/vsprojects/vs2013/gpr_test_util.vcxproj b/vsprojects/vs2013/gpr_test_util.vcxproj index 04caa7e9b1..e0608b31fc 100644 --- a/vsprojects/vs2013/gpr_test_util.vcxproj +++ b/vsprojects/vs2013/gpr_test_util.vcxproj @@ -78,6 +78,9 @@ </Link> </ItemDefinitionGroup> <ItemGroup> + <ClInclude Include="..\..\test\core\util\test_config.h" /> + </ItemGroup> + <ItemGroup> <ClCompile Include="..\..\test\core\util\test_config.c"> </ClCompile> </ItemGroup> diff --git a/vsprojects/vs2013/grpc++.vcxproj b/vsprojects/vs2013/grpc++.vcxproj index f0a623b79f..dff588166b 100644 --- a/vsprojects/vs2013/grpc++.vcxproj +++ b/vsprojects/vs2013/grpc++.vcxproj @@ -78,7 +78,9 @@ </Link> </ItemDefinitionGroup> <ItemGroup> + <ClInclude Include="..\..\include\grpc++\async_generic_service.h" /> <ClInclude Include="..\..\include\grpc++\async_unary_call.h" /> + <ClInclude Include="..\..\include\grpc++\byte_buffer.h" /> <ClInclude Include="..\..\include\grpc++\channel_arguments.h" /> <ClInclude Include="..\..\include\grpc++\channel_interface.h" /> <ClInclude Include="..\..\include\grpc++\client_context.h" /> @@ -86,22 +88,32 @@ <ClInclude Include="..\..\include\grpc++\config.h" /> <ClInclude Include="..\..\include\grpc++\create_channel.h" /> <ClInclude Include="..\..\include\grpc++\credentials.h" /> + <ClInclude Include="..\..\include\grpc++\generic_stub.h" /> <ClInclude Include="..\..\include\grpc++\impl\call.h" /> <ClInclude Include="..\..\include\grpc++\impl\client_unary_call.h" /> <ClInclude Include="..\..\include\grpc++\impl\internal_stub.h" /> <ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" /> <ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" /> <ClInclude Include="..\..\include\grpc++\impl\service_type.h" /> + <ClInclude Include="..\..\include\grpc++\impl\sync.h" /> + <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" /> + <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" /> + <ClInclude Include="..\..\include\grpc++\impl\thd.h" /> + <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" /> + <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" /> <ClInclude Include="..\..\include\grpc++\server.h" /> <ClInclude Include="..\..\include\grpc++\server_builder.h" /> <ClInclude Include="..\..\include\grpc++\server_context.h" /> <ClInclude Include="..\..\include\grpc++\server_credentials.h" /> + <ClInclude Include="..\..\include\grpc++\slice.h" /> <ClInclude Include="..\..\include\grpc++\status.h" /> <ClInclude Include="..\..\include\grpc++\status_code_enum.h" /> <ClInclude Include="..\..\include\grpc++\stream.h" /> <ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" /> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\src\cpp\client\secure_credentials.h" /> + <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" /> <ClInclude Include="..\..\src\cpp\client\channel.h" /> <ClInclude Include="..\..\src\cpp\proto\proto_utils.h" /> <ClInclude Include="..\..\src\cpp\server\thread_pool.h" /> @@ -124,6 +136,8 @@ </ClCompile> <ClCompile Include="..\..\src\cpp\client\credentials.cc"> </ClCompile> + <ClCompile Include="..\..\src\cpp\client\generic_stub.cc"> + </ClCompile> <ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc"> </ClCompile> <ClCompile Include="..\..\src\cpp\client\internal_stub.cc"> @@ -136,6 +150,8 @@ </ClCompile> <ClCompile Include="..\..\src\cpp\proto\proto_utils.cc"> </ClCompile> + <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc"> + </ClCompile> <ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc"> </ClCompile> <ClCompile Include="..\..\src\cpp\server\server.cc"> @@ -148,6 +164,10 @@ </ClCompile> <ClCompile Include="..\..\src\cpp\server\thread_pool.cc"> </ClCompile> + <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc"> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\slice.cc"> + </ClCompile> <ClCompile Include="..\..\src\cpp\util\status.cc"> </ClCompile> <ClCompile Include="..\..\src\cpp\util\time.cc"> diff --git a/vsprojects/vs2013/grpc++.vcxproj.filters b/vsprojects/vs2013/grpc++.vcxproj.filters index 34ebb170ff..6466a0fa26 100644 --- a/vsprojects/vs2013/grpc++.vcxproj.filters +++ b/vsprojects/vs2013/grpc++.vcxproj.filters @@ -25,6 +25,9 @@ <ClCompile Include="..\..\src\cpp\client\credentials.cc"> <Filter>src\cpp\client</Filter> </ClCompile> + <ClCompile Include="..\..\src\cpp\client\generic_stub.cc"> + <Filter>src\cpp\client</Filter> + </ClCompile> <ClCompile Include="..\..\src\cpp\client\insecure_credentials.cc"> <Filter>src\cpp\client</Filter> </ClCompile> @@ -43,6 +46,9 @@ <ClCompile Include="..\..\src\cpp\proto\proto_utils.cc"> <Filter>src\cpp\proto</Filter> </ClCompile> + <ClCompile Include="..\..\src\cpp\server\async_generic_service.cc"> + <Filter>src\cpp\server</Filter> + </ClCompile> <ClCompile Include="..\..\src\cpp\server\insecure_server_credentials.cc"> <Filter>src\cpp\server</Filter> </ClCompile> @@ -61,6 +67,12 @@ <ClCompile Include="..\..\src\cpp\server\thread_pool.cc"> <Filter>src\cpp\server</Filter> </ClCompile> + <ClCompile Include="..\..\src\cpp\util\byte_buffer.cc"> + <Filter>src\cpp\util</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cpp\util\slice.cc"> + <Filter>src\cpp\util</Filter> + </ClCompile> <ClCompile Include="..\..\src\cpp\util\status.cc"> <Filter>src\cpp\util</Filter> </ClCompile> @@ -69,9 +81,15 @@ </ClCompile> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\include\grpc++\async_generic_service.h"> + <Filter>include\grpc++</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc++\async_unary_call.h"> <Filter>include\grpc++</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc++\byte_buffer.h"> + <Filter>include\grpc++</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc++\channel_arguments.h"> <Filter>include\grpc++</Filter> </ClInclude> @@ -93,6 +111,9 @@ <ClInclude Include="..\..\include\grpc++\credentials.h"> <Filter>include\grpc++</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc++\generic_stub.h"> + <Filter>include\grpc++</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc++\impl\call.h"> <Filter>include\grpc++\impl</Filter> </ClInclude> @@ -111,6 +132,24 @@ <ClInclude Include="..\..\include\grpc++\impl\service_type.h"> <Filter>include\grpc++\impl</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\sync.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\thd.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc++\server.h"> <Filter>include\grpc++</Filter> </ClInclude> @@ -123,6 +162,9 @@ <ClInclude Include="..\..\include\grpc++\server_credentials.h"> <Filter>include\grpc++</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc++\slice.h"> + <Filter>include\grpc++</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc++\status.h"> <Filter>include\grpc++</Filter> </ClInclude> @@ -137,6 +179,12 @@ </ClInclude> </ItemGroup> <ItemGroup> + <ClInclude Include="..\..\src\cpp\client\secure_credentials.h"> + <Filter>src\cpp\client</Filter> + </ClInclude> + <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h"> + <Filter>src\cpp\server</Filter> + </ClInclude> <ClInclude Include="..\..\src\cpp\client\channel.h"> <Filter>src\cpp\client</Filter> </ClInclude> diff --git a/vsprojects/vs2013/grpc.sln b/vsprojects/vs2013/grpc.sln index a3915b3591..dfefddfbbd 100644 --- a/vsprojects/vs2013/grpc.sln +++ b/vsprojects/vs2013/grpc.sln @@ -18,6 +18,7 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}" ProjectSection(ProjectDependencies) = postProject {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037} {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} EndProjectSection EndProject @@ -38,10 +39,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext", "grpc_csh {29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_shared", "gpr_shared.vcxproj", "{3D304D6B-AAF8-428B-AC7D-A698DDDE93C0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_shared", "grpc_shared.vcxproj", "{F2EE8FDB-F1E0-43A0-A297-6F255BB52AAA}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext_shared", "grpc_csharp_ext_shared.vcxproj", "{C26D04A8-37C6-44C7-B458-906C9FCE928C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "third_party\zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}" diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj index 9d0bcb3271..a88eb34ab8 100644 --- a/vsprojects/vs2013/grpc.vcxproj +++ b/vsprojects/vs2013/grpc.vcxproj @@ -82,6 +82,7 @@ <ClInclude Include="..\..\include\grpc\byte_buffer.h" /> <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" /> <ClInclude Include="..\..\include\grpc\grpc.h" /> + <ClInclude Include="..\..\include\grpc\grpc_http.h" /> <ClInclude Include="..\..\include\grpc\status.h" /> </ItemGroup> <ItemGroup> @@ -93,6 +94,7 @@ <ClInclude Include="..\..\src\core\security\base64.h" /> <ClInclude Include="..\..\src\core\security\credentials.h" /> <ClInclude Include="..\..\src\core\security\json_token.h" /> + <ClInclude Include="..\..\src\core\security\secure_endpoint.h" /> <ClInclude Include="..\..\src\core\security\secure_transport_setup.h" /> <ClInclude Include="..\..\src\core\security\security_context.h" /> <ClInclude Include="..\..\src\core\tsi\fake_transport_security.h" /> @@ -163,6 +165,7 @@ <ClInclude Include="..\..\src\core\surface\init.h" /> <ClInclude Include="..\..\src\core\surface\server.h" /> <ClInclude Include="..\..\src\core\surface\surface_trace.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\frame.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" /> @@ -355,6 +358,8 @@ </ClCompile> <ClCompile Include="..\..\src\core\surface\call_details.c"> </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + </ClCompile> <ClCompile Include="..\..\src\core\surface\channel.c"> </ClCompile> <ClCompile Include="..\..\src\core\surface\channel_create.c"> diff --git a/vsprojects/vs2013/grpc.vcxproj.filters b/vsprojects/vs2013/grpc.vcxproj.filters index af38d8de35..20dbe8c444 100644 --- a/vsprojects/vs2013/grpc.vcxproj.filters +++ b/vsprojects/vs2013/grpc.vcxproj.filters @@ -253,6 +253,9 @@ <ClCompile Include="..\..\src\core\surface\call_details.c"> <Filter>src\core\surface</Filter> </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + <Filter>src\core\surface</Filter> + </ClCompile> <ClCompile Include="..\..\src\core\surface\channel.c"> <Filter>src\core\surface</Filter> </ClCompile> @@ -363,6 +366,9 @@ <ClInclude Include="..\..\include\grpc\grpc.h"> <Filter>include\grpc</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc\grpc_http.h"> + <Filter>include\grpc</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc\status.h"> <Filter>include\grpc</Filter> </ClInclude> @@ -392,6 +398,9 @@ <ClInclude Include="..\..\src\core\security\json_token.h"> <Filter>src\core\security</Filter> </ClInclude> + <ClInclude Include="..\..\src\core\security\secure_endpoint.h"> + <Filter>src\core\security</Filter> + </ClInclude> <ClInclude Include="..\..\src\core\security\secure_transport_setup.h"> <Filter>src\core\security</Filter> </ClInclude> @@ -602,6 +611,9 @@ <ClInclude Include="..\..\src\core\surface\surface_trace.h"> <Filter>src\core\surface</Filter> </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h"> <Filter>src\core\transport\chttp2</Filter> </ClInclude> diff --git a/vsprojects/vs2013/grpc_test_util.vcxproj b/vsprojects/vs2013/grpc_test_util.vcxproj index 7269671bd3..4756f53928 100644 --- a/vsprojects/vs2013/grpc_test_util.vcxproj +++ b/vsprojects/vs2013/grpc_test_util.vcxproj @@ -105,6 +105,9 @@ <ProjectReference Include="gpr.vcxproj"> <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> </ProjectReference> + <ProjectReference Include="gpr_test_util.vcxproj"> + <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project> + </ProjectReference> <ProjectReference Include="grpc.vcxproj"> <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project> </ProjectReference> diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj b/vsprojects/vs2013/grpc_unsecure.vcxproj index ad7bf4762f..98c14c2fdb 100644 --- a/vsprojects/vs2013/grpc_unsecure.vcxproj +++ b/vsprojects/vs2013/grpc_unsecure.vcxproj @@ -81,6 +81,7 @@ <ClInclude Include="..\..\include\grpc\byte_buffer.h" /> <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" /> <ClInclude Include="..\..\include\grpc\grpc.h" /> + <ClInclude Include="..\..\include\grpc\grpc_http.h" /> <ClInclude Include="..\..\include\grpc\status.h" /> </ItemGroup> <ItemGroup> @@ -148,6 +149,7 @@ <ClInclude Include="..\..\src\core\surface\init.h" /> <ClInclude Include="..\..\src\core\surface\server.h" /> <ClInclude Include="..\..\src\core\surface\surface_trace.h" /> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\frame.h" /> <ClInclude Include="..\..\src\core\transport\chttp2\frame_data.h" /> @@ -300,6 +302,8 @@ </ClCompile> <ClCompile Include="..\..\src\core\surface\call_details.c"> </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + </ClCompile> <ClCompile Include="..\..\src\core\surface\channel.c"> </ClCompile> <ClCompile Include="..\..\src\core\surface\channel_create.c"> diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters index 205942a450..4b758d6113 100644 --- a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters @@ -193,6 +193,9 @@ <ClCompile Include="..\..\src\core\surface\call_details.c"> <Filter>src\core\surface</Filter> </ClCompile> + <ClCompile Include="..\..\src\core\surface\call_log_batch.c"> + <Filter>src\core\surface</Filter> + </ClCompile> <ClCompile Include="..\..\src\core\surface\channel.c"> <Filter>src\core\surface</Filter> </ClCompile> @@ -300,6 +303,9 @@ <ClInclude Include="..\..\include\grpc\grpc.h"> <Filter>include\grpc</Filter> </ClInclude> + <ClInclude Include="..\..\include\grpc\grpc_http.h"> + <Filter>include\grpc</Filter> + </ClInclude> <ClInclude Include="..\..\include\grpc\status.h"> <Filter>include\grpc</Filter> </ClInclude> @@ -497,6 +503,9 @@ <ClInclude Include="..\..\src\core\surface\surface_trace.h"> <Filter>src\core\surface</Filter> </ClInclude> + <ClInclude Include="..\..\src\core\transport\chttp2\alpn.h"> + <Filter>src\core\transport\chttp2</Filter> + </ClInclude> <ClInclude Include="..\..\src\core\transport\chttp2\bin_encoder.h"> <Filter>src\core\transport\chttp2</Filter> </ClInclude> |