Merge branch 'latent-see' into try-this-simple-trick-to-double-performance

pull/3786/head
Craig Tiller 9 years ago
commit 2783ced6f4
  1. 3
      BUILD
  2. 236
      binding.gyp
  3. 1
      build.yaml
  4. 2
      gRPC.podspec
  5. 296
      grpc.gyp
  6. 12
      include/grpc/support/port_platform.h
  7. 3
      package.json
  8. 4
      src/core/channel/client_channel.c
  9. 2
      src/core/channel/compress_filter.c
  10. 4
      src/core/client_config/uri_parser.c
  11. 11
      src/core/httpcli/parser.c
  12. 2
      src/core/iomgr/tcp_client_posix.c
  13. 2
      src/core/iomgr/tcp_server_posix.c
  14. 42
      src/core/security/credentials.c
  15. 8
      src/core/security/credentials.h
  16. 26
      src/core/security/security_context.c
  17. 11
      src/core/security/security_context.h
  18. 36
      src/core/security/server_auth_filter.c
  19. 4
      src/core/security/server_secure_chttp2.c
  20. 8
      src/core/surface/byte_buffer.c
  21. 29
      src/core/surface/call.c
  22. 11
      src/core/surface/call.h
  23. 65
      src/core/surface/call_test_only.h
  24. 8
      src/core/surface/channel_connectivity.c
  25. 3
      src/core/surface/completion_queue.c
  26. 4
      src/core/transport/chttp2/frame_data.c
  27. 4
      src/core/transport/chttp2/frame_goaway.c
  28. 8
      src/core/transport/chttp2/hpack_parser.c
  29. 16
      src/core/transport/chttp2/parsing.c
  30. 6
      src/core/transport/chttp2/stream_encoder.c
  31. 3
      src/cpp/server/server.cc
  32. 188
      src/node/interop/interop_client.js
  33. 63
      src/node/interop/interop_server.js
  34. 2
      src/node/src/credentials.js
  35. 2
      src/node/src/server.js
  36. 2
      src/node/test/async_test.js
  37. 2
      src/node/test/channel_test.js
  38. 10
      src/node/test/credentials_test.js
  39. 10
      src/node/test/interop_sanity_test.js
  40. 20
      src/php/tests/interop/interop_client.php
  41. 116
      templates/binding.gyp.template
  42. 11
      test/core/end2end/tests/compressed_payload.c
  43. 6
      test/cpp/interop/client_helper.h
  44. 6
      test/cpp/interop/server_helper.cc
  45. 16
      test/cpp/qps/driver.cc
  46. 1
      tools/doxygen/Doxyfile.core.internal
  47. 14
      tools/jenkins/build_docker_and_run_tests.sh
  48. 11
      tools/jenkins/build_interop_image.sh
  49. 1
      tools/jenkins/grpc_interop_node/Dockerfile
  50. 3
      tools/jenkins/grpc_interop_node/build_interop.sh
  51. 6
      tools/jenkins/grpc_jenkins_slave/Dockerfile
  52. 57
      tools/run_tests/dockerjob.py
  53. 6
      tools/run_tests/jobset.py
  54. 52
      tools/run_tests/run_interop_tests.py
  55. 2
      tools/run_tests/run_node.sh
  56. 5
      tools/run_tests/run_tests.py
  57. 4
      tools/run_tests/sources_and_headers.json
  58. 1
      vsprojects/vcxproj/grpc/grpc.vcxproj
  59. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  60. 1
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  61. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -226,6 +226,7 @@ cc_library(
"src/core/surface/api_trace.h", "src/core/surface/api_trace.h",
"src/core/surface/byte_buffer_queue.h", "src/core/surface/byte_buffer_queue.h",
"src/core/surface/call.h", "src/core/surface/call.h",
"src/core/surface/call_test_only.h",
"src/core/surface/channel.h", "src/core/surface/channel.h",
"src/core/surface/completion_queue.h", "src/core/surface/completion_queue.h",
"src/core/surface/event_string.h", "src/core/surface/event_string.h",
@ -509,6 +510,7 @@ cc_library(
"src/core/surface/api_trace.h", "src/core/surface/api_trace.h",
"src/core/surface/byte_buffer_queue.h", "src/core/surface/byte_buffer_queue.h",
"src/core/surface/call.h", "src/core/surface/call.h",
"src/core/surface/call_test_only.h",
"src/core/surface/channel.h", "src/core/surface/channel.h",
"src/core/surface/completion_queue.h", "src/core/surface/completion_queue.h",
"src/core/surface/event_string.h", "src/core/surface/event_string.h",
@ -1295,6 +1297,7 @@ objc_library(
"src/core/surface/api_trace.h", "src/core/surface/api_trace.h",
"src/core/surface/byte_buffer_queue.h", "src/core/surface/byte_buffer_queue.h",
"src/core/surface/call.h", "src/core/surface/call.h",
"src/core/surface/call_test_only.h",
"src/core/surface/channel.h", "src/core/surface/channel.h",
"src/core/surface/completion_queue.h", "src/core/surface/completion_queue.h",
"src/core/surface/event_string.h", "src/core/surface/event_string.h",

@ -1,3 +1,10 @@
# GRPC Node gyp file
# This currently builds the Node extension and dependencies
# This file has been automatically generated from a template file.
# Please look at the templates directory instead.
# This file can be regenerated from the template by running
# tools/buildgen/generate_projects.sh
# Copyright 2015, Google Inc. # Copyright 2015, Google Inc.
# All rights reserved. # All rights reserved.
# #
@ -26,11 +33,234 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Some of this file is built with the help of
# https://n8.io/converting-a-c-library-to-gyp/
{ {
"variables" : { 'variables': {
'config': '<!(echo $CONFIG)' 'config': '<!(echo $CONFIG)'
}, },
"targets" : [ # TODO: Finish windows support
'target_defaults': {
# Empirically, Node only exports ALPN symbols if its major version is >0.
# io.js always reports versions >0 and always exports ALPN symbols.
# Therefore, Node's major version will be truthy if and only if it
# supports ALPN. The output of "node -v" is v[major].[minor].[patch],
# like "v4.1.1" in a recent version. We use grep to extract just the
# major version. "4", would be the output for the example.
'defines': [
'TSI_OPENSSL_ALPN_SUPPORT=<!(node -v | grep -oP "(?<=v)(\d+)(?=\.\d+\.\d+)")'
],
'include_dirs': [
'.',
'include'
]
},
'targets': [
{
'target_name': 'gpr',
'product_prefix': 'lib',
'type': 'static_library',
'dependencies': [
],
'sources': [
'src/core/support/alloc.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/stack_lockfree.c',
'src/core/support/string.c',
'src/core/support/string_posix.c',
'src/core/support/string_win32.c',
'src/core/support/subprocess_posix.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',
'src/core/support/tls_pthread.c',
],
},
{
'target_name': 'grpc',
'product_prefix': 'lib',
'type': 'static_library',
'dependencies': [
'gpr',
],
'sources': [
'src/core/httpcli/httpcli_security_connector.c',
'src/core/security/base64.c',
'src/core/security/client_auth_filter.c',
'src/core/security/credentials.c',
'src/core/security/credentials_metadata.c',
'src/core/security/credentials_posix.c',
'src/core/security/credentials_win32.c',
'src/core/security/google_default_credentials.c',
'src/core/security/handshake.c',
'src/core/security/json_token.c',
'src/core/security/jwt_verifier.c',
'src/core/security/secure_endpoint.c',
'src/core/security/security_connector.c',
'src/core/security/security_context.c',
'src/core/security/server_auth_filter.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/census/grpc_context.c',
'src/core/census/grpc_filter.c',
'src/core/channel/channel_args.c',
'src/core/channel/channel_stack.c',
'src/core/channel/client_channel.c',
'src/core/channel/compress_filter.c',
'src/core/channel/connected_channel.c',
'src/core/channel/http_client_filter.c',
'src/core/channel/http_server_filter.c',
'src/core/channel/noop_filter.c',
'src/core/client_config/client_config.c',
'src/core/client_config/connector.c',
'src/core/client_config/lb_policies/pick_first.c',
'src/core/client_config/lb_policies/round_robin.c',
'src/core/client_config/lb_policy.c',
'src/core/client_config/lb_policy_factory.c',
'src/core/client_config/lb_policy_registry.c',
'src/core/client_config/resolver.c',
'src/core/client_config/resolver_factory.c',
'src/core/client_config/resolver_registry.c',
'src/core/client_config/resolvers/dns_resolver.c',
'src/core/client_config/resolvers/sockaddr_resolver.c',
'src/core/client_config/subchannel.c',
'src/core/client_config/subchannel_factory.c',
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.c',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.c',
'src/core/client_config/uri_parser.c',
'src/core/compression/algorithm.c',
'src/core/compression/message_compress.c',
'src/core/debug/trace.c',
'src/core/httpcli/format_request.c',
'src/core/httpcli/httpcli.c',
'src/core/httpcli/parser.c',
'src/core/iomgr/alarm.c',
'src/core/iomgr/alarm_heap.c',
'src/core/iomgr/closure.c',
'src/core/iomgr/endpoint.c',
'src/core/iomgr/endpoint_pair_posix.c',
'src/core/iomgr/endpoint_pair_windows.c',
'src/core/iomgr/exec_ctx.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_multipoller_with_epoll.c',
'src/core/iomgr/pollset_multipoller_with_poll_posix.c',
'src/core/iomgr/pollset_posix.c',
'src/core/iomgr/pollset_set_posix.c',
'src/core/iomgr/pollset_set_windows.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/udp_server.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/iomgr/workqueue_posix.c',
'src/core/iomgr/workqueue_windows.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/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/surface/api_trace.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_connectivity.c',
'src/core/surface/channel_create.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/version.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/incoming_metadata.c',
'src/core/transport/chttp2/parsing.c',
'src/core/transport/chttp2/status_conversion.c',
'src/core/transport/chttp2/stream_encoder.c',
'src/core/transport/chttp2/stream_lists.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/writing.c',
'src/core/transport/chttp2_transport.c',
'src/core/transport/connectivity_state.c',
'src/core/transport/metadata.c',
'src/core/transport/stream_op.c',
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/census/context.c',
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/tracing.c',
],
},
{ {
'include_dirs': [ 'include_dirs': [
"<!(node -e \"require('nan')\")" "<!(node -e \"require('nan')\")"
@ -88,7 +318,7 @@
"src/node/ext/timeval.cc" "src/node/ext/timeval.cc"
], ],
"dependencies": [ "dependencies": [
"grpc.gyp:grpc" "grpc"
] ]
} }
] ]

@ -182,6 +182,7 @@ filegroups:
- src/core/surface/api_trace.h - src/core/surface/api_trace.h
- src/core/surface/byte_buffer_queue.h - src/core/surface/byte_buffer_queue.h
- src/core/surface/call.h - src/core/surface/call.h
- src/core/surface/call_test_only.h
- src/core/surface/channel.h - src/core/surface/channel.h
- src/core/surface/completion_queue.h - src/core/surface/completion_queue.h
- src/core/surface/event_string.h - src/core/surface/event_string.h

@ -230,6 +230,7 @@ Pod::Spec.new do |s|
'src/core/surface/api_trace.h', 'src/core/surface/api_trace.h',
'src/core/surface/byte_buffer_queue.h', 'src/core/surface/byte_buffer_queue.h',
'src/core/surface/call.h', 'src/core/surface/call.h',
'src/core/surface/call_test_only.h',
'src/core/surface/channel.h', 'src/core/surface/channel.h',
'src/core/surface/completion_queue.h', 'src/core/surface/completion_queue.h',
'src/core/surface/event_string.h', 'src/core/surface/event_string.h',
@ -519,6 +520,7 @@ Pod::Spec.new do |s|
'src/core/surface/api_trace.h', 'src/core/surface/api_trace.h',
'src/core/surface/byte_buffer_queue.h', 'src/core/surface/byte_buffer_queue.h',
'src/core/surface/call.h', 'src/core/surface/call.h',
'src/core/surface/call_test_only.h',
'src/core/surface/channel.h', 'src/core/surface/channel.h',
'src/core/surface/completion_queue.h', 'src/core/surface/completion_queue.h',
'src/core/surface/event_string.h', 'src/core/surface/event_string.h',

@ -1,296 +0,0 @@
# GRPC gyp file
# This currently builds C code.
# This file has been automatically generated from a template file.
# Please look at the templates directory instead.
# This file can be regenerated from the template by running
# tools/buildgen/generate_projects.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.
# Some of this file is built with the help of
# https://n8.io/converting-a-c-library-to-gyp/
{
# TODO: Finish windows support
'target_defaults': {
'default_configuration': 'Debug',
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 1, # static debug
},
},
},
'Release': {
'defines': [ 'NDEBUG' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 0, # static release
},
},
}
},
'msvs_settings': {
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
},
},
# TODO: Add fallback for Windows, and if pkg-config is not available
'defines': [
'TSI_OPENSSL_ALPN_SUPPORT=<!(pkg-config --atleast-version=1.0.2 openssl >/dev/null 2>&1 && echo 1 || echo 0)'
],
'include_dirs': [
'.',
'include'
],
# TODO: Check for libraries with pkg-config
'libraries': [
'-lcrypto',
'-lssl',
'-ldl',
'-lpthread',
'-lz'
],
'direct_dependent_settings': {
'include_dirs': [
'.',
'include'
],
}
},
'targets': [
{
'target_name': 'gpr',
'product_prefix': 'lib',
'type': 'static_library',
'dependencies': [
],
'sources': [
'src/core/profiling/basic_timers.c',
'src/core/profiling/stap_timers.c',
'src/core/support/alloc.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/stack_lockfree.c',
'src/core/support/string.c',
'src/core/support/string_posix.c',
'src/core/support/string_win32.c',
'src/core/support/subprocess_posix.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_precise.c',
'src/core/support/time_win32.c',
'src/core/support/tls_pthread.c',
],
},
{
'target_name': 'grpc',
'product_prefix': 'lib',
'type': 'static_library',
'dependencies': [
'gpr',
],
'sources': [
'src/core/httpcli/httpcli_security_connector.c',
'src/core/security/base64.c',
'src/core/security/client_auth_filter.c',
'src/core/security/credentials.c',
'src/core/security/credentials_metadata.c',
'src/core/security/credentials_posix.c',
'src/core/security/credentials_win32.c',
'src/core/security/google_default_credentials.c',
'src/core/security/handshake.c',
'src/core/security/json_token.c',
'src/core/security/jwt_verifier.c',
'src/core/security/secure_endpoint.c',
'src/core/security/security_connector.c',
'src/core/security/security_context.c',
'src/core/security/server_auth_filter.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/census/grpc_context.c',
'src/core/census/grpc_filter.c',
'src/core/channel/channel_args.c',
'src/core/channel/channel_stack.c',
'src/core/channel/client_channel.c',
'src/core/channel/compress_filter.c',
'src/core/channel/connected_channel.c',
'src/core/channel/http_client_filter.c',
'src/core/channel/http_server_filter.c',
'src/core/channel/noop_filter.c',
'src/core/client_config/client_config.c',
'src/core/client_config/connector.c',
'src/core/client_config/lb_policies/pick_first.c',
'src/core/client_config/lb_policies/round_robin.c',
'src/core/client_config/lb_policy.c',
'src/core/client_config/lb_policy_factory.c',
'src/core/client_config/lb_policy_registry.c',
'src/core/client_config/resolver.c',
'src/core/client_config/resolver_factory.c',
'src/core/client_config/resolver_registry.c',
'src/core/client_config/resolvers/dns_resolver.c',
'src/core/client_config/resolvers/sockaddr_resolver.c',
'src/core/client_config/subchannel.c',
'src/core/client_config/subchannel_factory.c',
'src/core/client_config/subchannel_factory_decorators/add_channel_arg.c',
'src/core/client_config/subchannel_factory_decorators/merge_channel_args.c',
'src/core/client_config/uri_parser.c',
'src/core/compression/algorithm.c',
'src/core/compression/message_compress.c',
'src/core/debug/trace.c',
'src/core/httpcli/format_request.c',
'src/core/httpcli/httpcli.c',
'src/core/httpcli/parser.c',
'src/core/iomgr/alarm.c',
'src/core/iomgr/alarm_heap.c',
'src/core/iomgr/closure.c',
'src/core/iomgr/endpoint.c',
'src/core/iomgr/endpoint_pair_posix.c',
'src/core/iomgr/endpoint_pair_windows.c',
'src/core/iomgr/exec_ctx.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_multipoller_with_epoll.c',
'src/core/iomgr/pollset_multipoller_with_poll_posix.c',
'src/core/iomgr/pollset_posix.c',
'src/core/iomgr/pollset_set_posix.c',
'src/core/iomgr/pollset_set_windows.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/udp_server.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/iomgr/workqueue_posix.c',
'src/core/iomgr/workqueue_windows.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/surface/api_trace.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_connectivity.c',
'src/core/surface/channel_create.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/version.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/incoming_metadata.c',
'src/core/transport/chttp2/parsing.c',
'src/core/transport/chttp2/status_conversion.c',
'src/core/transport/chttp2/stream_encoder.c',
'src/core/transport/chttp2/stream_lists.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/writing.c',
'src/core/transport/chttp2_transport.c',
'src/core/transport/connectivity_state.c',
'src/core/transport/metadata.c',
'src/core/transport/stream_op.c',
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/census/context.c',
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/tracing.c',
],
},
]
}

@ -181,6 +181,7 @@
#ifndef _BSD_SOURCE #ifndef _BSD_SOURCE
#define _BSD_SOURCE #define _BSD_SOURCE
#endif #endif
#define GPR_FORBID_UNREACHABLE_CODE
#define GPR_MSG_IOVLEN_TYPE int #define GPR_MSG_IOVLEN_TYPE int
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
#define GPR_PLATFORM_STRING "ios" #define GPR_PLATFORM_STRING "ios"
@ -336,4 +337,15 @@ typedef uintptr_t gpr_uintptr;
#endif #endif
#endif #endif
#ifdef GPR_FORBID_UNREACHABLE_CODE
#define GPR_UNREACHABLE_CODE(STATEMENT)
#else
#define GPR_UNREACHABLE_CODE(STATEMENT) \
do { \
gpr_log(GPR_ERROR, "Should never reach here."); \
abort(); \
STATEMENT; \
} while (0)
#endif /* GPR_FORBID_UNREACHABLE_CODE */
#endif /* GRPC_SUPPORT_PORT_PLATFORM_H */ #endif /* GRPC_SUPPORT_PORT_PLATFORM_H */

@ -19,7 +19,7 @@
"lib": "src/node/src" "lib": "src/node/src"
}, },
"scripts": { "scripts": {
"lint": "node ./node_modules/jshint/bin/jshint src/node/src src/node/test src/node/examples src/node/interop src/node/index.js", "lint": "node ./node_modules/jshint/bin/jshint src/node/src src/node/test src/node/interop src/node/index.js",
"test": "./node_modules/.bin/mocha src/node/test && npm run-script lint", "test": "./node_modules/.bin/mocha src/node/test && npm run-script lint",
"gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json", "gen_docs": "./node_modules/.bin/jsdoc -c src/node/jsdoc_conf.json",
"coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test" "coverage": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha src/node/test"
@ -53,7 +53,6 @@
"src/core", "src/core",
"test/proto", "test/proto",
"include", "include",
"grpc.gyp",
"binding.gyp" "binding.gyp"
], ],
"main": "src/node/index.js", "main": "src/node/index.js",

@ -654,9 +654,7 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
case CALL_WAITING_FOR_CONFIG: case CALL_WAITING_FOR_CONFIG:
case CALL_WAITING_FOR_CALL: case CALL_WAITING_FOR_CALL:
case CALL_WAITING_FOR_SEND: case CALL_WAITING_FOR_SEND:
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return );
abort();
break;
} }
} }

@ -243,7 +243,7 @@ static void process_send_ops(grpc_call_element *elem,
GPR_ASSERT(calld->remaining_slice_bytes > 0); GPR_ASSERT(calld->remaining_slice_bytes > 0);
/* Increase input ref count, gpr_slice_buffer_add takes ownership. */ /* Increase input ref count, gpr_slice_buffer_add takes ownership. */
gpr_slice_buffer_add(&calld->slices, gpr_slice_ref(sop->data.slice)); gpr_slice_buffer_add(&calld->slices, gpr_slice_ref(sop->data.slice));
GPR_ASSERT(GPR_SLICE_LENGTH(sop->data.slice) >= GPR_ASSERT(GPR_SLICE_LENGTH(sop->data.slice) <=
calld->remaining_slice_bytes); calld->remaining_slice_bytes);
calld->remaining_slice_bytes -= calld->remaining_slice_bytes -=
(gpr_uint32)GPR_SLICE_LENGTH(sop->data.slice); (gpr_uint32)GPR_SLICE_LENGTH(sop->data.slice);

@ -37,6 +37,7 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
/** a size_t default value... maps to all 1's */ /** a size_t default value... maps to all 1's */
@ -120,8 +121,7 @@ static int parse_fragment_or_query(const char *uri_text, size_t *i) {
} else { } else {
return 1; return 1;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
default: default:
(*i) += advance; (*i) += advance;
break; break;

@ -139,8 +139,7 @@ static int finish_line(grpc_httpcli_parser *parser) {
} }
break; break;
case GRPC_HTTPCLI_BODY: case GRPC_HTTPCLI_BODY:
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
} }
parser->cur_line_length = 0; parser->cur_line_length = 0;
@ -165,8 +164,7 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) {
} else { } else {
return 1; return 1;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
case GRPC_HTTPCLI_BODY: case GRPC_HTTPCLI_BODY:
if (parser->r.body_length == parser->body_capacity) { if (parser->r.body_length == parser->body_capacity) {
parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2); parser->body_capacity = GPR_MAX(8, parser->body_capacity * 3 / 2);
@ -177,10 +175,7 @@ static int addbyte(grpc_httpcli_parser *parser, gpr_uint8 byte) {
parser->r.body_length++; parser->r.body_length++;
return 1; return 1;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
return 0;
} }
void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) { void grpc_httpcli_parser_init(grpc_httpcli_parser *parser) {

@ -191,7 +191,7 @@ static void on_writable(grpc_exec_ctx *exec_ctx, void *acp, int success) {
goto finish; goto finish;
} }
abort(); GPR_UNREACHABLE_CODE(return );
finish: finish:
if (fd != NULL) { if (fd != NULL) {

@ -352,7 +352,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
gpr_free(addr_str); gpr_free(addr_str);
} }
abort(); GPR_UNREACHABLE_CODE(return );
error: error:
gpr_mu_lock(&sp->server->mu); gpr_mu_lock(&sp->server->mu);

@ -181,6 +181,48 @@ void grpc_server_credentials_set_auth_metadata_processor(
creds->processor = processor; creds->processor = processor;
} }
static void server_credentials_pointer_arg_destroy(void *p) {
grpc_server_credentials_unref(p);
}
static void *server_credentials_pointer_arg_copy(void *p) {
return grpc_server_credentials_ref(p);
}
grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *p) {
grpc_arg arg;
memset(&arg, 0, sizeof(grpc_arg));
arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_SERVER_CREDENTIALS_ARG;
arg.value.pointer.p = p;
arg.value.pointer.copy = server_credentials_pointer_arg_copy;
arg.value.pointer.destroy = server_credentials_pointer_arg_destroy;
return arg;
}
grpc_server_credentials *grpc_server_credentials_from_arg(
const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_SERVER_CREDENTIALS_ARG) != 0) return NULL;
if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
GRPC_SERVER_CREDENTIALS_ARG);
return NULL;
}
return arg->value.pointer.p;
}
grpc_server_credentials *grpc_find_server_credentials_in_args(
const grpc_channel_args *args) {
size_t i;
if (args == NULL) return NULL;
for (i = 0; i < args->num_args; i++) {
grpc_server_credentials *p =
grpc_server_credentials_from_arg(&args->args[i]);
if (p != NULL) return p;
}
return NULL;
}
/* -- Ssl credentials. -- */ /* -- Ssl credentials. -- */
static void ssl_destruct(grpc_credentials *creds) { static void ssl_destruct(grpc_credentials *creds) {

@ -215,7 +215,6 @@ typedef struct {
grpc_server_credentials *c, grpc_security_connector **sc); grpc_server_credentials *c, grpc_security_connector **sc);
} grpc_server_credentials_vtable; } grpc_server_credentials_vtable;
/* TODO(jboeuf): Add a refcount. */
struct grpc_server_credentials { struct grpc_server_credentials {
const grpc_server_credentials_vtable *vtable; const grpc_server_credentials_vtable *vtable;
const char *type; const char *type;
@ -231,6 +230,13 @@ grpc_server_credentials *grpc_server_credentials_ref(
void grpc_server_credentials_unref(grpc_server_credentials *creds); void grpc_server_credentials_unref(grpc_server_credentials *creds);
#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials"
grpc_arg grpc_server_credentials_to_arg(grpc_server_credentials *c);
grpc_server_credentials *grpc_server_credentials_from_arg(const grpc_arg *arg);
grpc_server_credentials *grpc_find_server_credentials_in_args(
const grpc_channel_args *args);
/* -- Ssl credentials. -- */ /* -- Ssl credentials. -- */
typedef struct { typedef struct {

@ -305,33 +305,43 @@ void grpc_auth_property_reset(grpc_auth_property *property) {
memset(property, 0, sizeof(grpc_auth_property)); memset(property, 0, sizeof(grpc_auth_property));
} }
grpc_arg grpc_auth_metadata_processor_to_arg(grpc_auth_metadata_processor *p) { static void auth_context_pointer_arg_destroy(void *p) {
GRPC_AUTH_CONTEXT_UNREF(p, "auth_context_pointer_arg");
}
static void *auth_context_pointer_arg_copy(void *p) {
return GRPC_AUTH_CONTEXT_REF(p, "auth_context_pointer_arg");
}
grpc_arg grpc_auth_context_to_arg(grpc_auth_context *p) {
grpc_arg arg; grpc_arg arg;
memset(&arg, 0, sizeof(grpc_arg)); memset(&arg, 0, sizeof(grpc_arg));
arg.type = GRPC_ARG_POINTER; arg.type = GRPC_ARG_POINTER;
arg.key = GRPC_AUTH_METADATA_PROCESSOR_ARG; arg.key = GRPC_AUTH_CONTEXT_ARG;
arg.value.pointer.p = p; arg.value.pointer.p = p;
arg.value.pointer.copy = auth_context_pointer_arg_copy;
arg.value.pointer.destroy = auth_context_pointer_arg_destroy;
return arg; return arg;
} }
grpc_auth_metadata_processor *grpc_auth_metadata_processor_from_arg( grpc_auth_context *grpc_auth_context_from_arg(
const grpc_arg *arg) { const grpc_arg *arg) {
if (strcmp(arg->key, GRPC_AUTH_METADATA_PROCESSOR_ARG) != 0) return NULL; if (strcmp(arg->key, GRPC_AUTH_CONTEXT_ARG) != 0) return NULL;
if (arg->type != GRPC_ARG_POINTER) { if (arg->type != GRPC_ARG_POINTER) {
gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type, gpr_log(GPR_ERROR, "Invalid type %d for arg %s", arg->type,
GRPC_AUTH_METADATA_PROCESSOR_ARG); GRPC_AUTH_CONTEXT_ARG);
return NULL; return NULL;
} }
return arg->value.pointer.p; return arg->value.pointer.p;
} }
grpc_auth_metadata_processor *grpc_find_auth_metadata_processor_in_args( grpc_auth_context *grpc_find_auth_context_in_args(
const grpc_channel_args *args) { const grpc_channel_args *args) {
size_t i; size_t i;
if (args == NULL) return NULL; if (args == NULL) return NULL;
for (i = 0; i < args->num_args; i++) { for (i = 0; i < args->num_args; i++) {
grpc_auth_metadata_processor *p = grpc_auth_context *p =
grpc_auth_metadata_processor_from_arg(&args->args[i]); grpc_auth_context_from_arg(&args->args[i]);
if (p != NULL) return p; if (p != NULL) return p;
} }
return NULL; return NULL;

@ -103,13 +103,12 @@ typedef struct {
grpc_server_security_context *grpc_server_security_context_create(void); grpc_server_security_context *grpc_server_security_context_create(void);
void grpc_server_security_context_destroy(void *ctx); void grpc_server_security_context_destroy(void *ctx);
/* --- Auth metadata processing. --- */ /* --- Channel args for auth context --- */
#define GRPC_AUTH_METADATA_PROCESSOR_ARG "grpc.auth_metadata_processor" #define GRPC_AUTH_CONTEXT_ARG "grpc.auth_context"
grpc_arg grpc_auth_metadata_processor_to_arg(grpc_auth_metadata_processor *p); grpc_arg grpc_auth_context_to_arg(grpc_auth_context *c);
grpc_auth_metadata_processor *grpc_auth_metadata_processor_from_arg( grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg);
const grpc_arg *arg); grpc_auth_context *grpc_find_auth_context_in_args(
grpc_auth_metadata_processor *grpc_find_auth_metadata_processor_in_args(
const grpc_channel_args *args); const grpc_channel_args *args);
#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */ #endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */

@ -34,7 +34,7 @@
#include <string.h> #include <string.h>
#include "src/core/security/auth_filters.h" #include "src/core/security/auth_filters.h"
#include "src/core/security/security_connector.h" #include "src/core/security/credentials.h"
#include "src/core/security/security_context.h" #include "src/core/security/security_context.h"
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
@ -58,8 +58,8 @@ typedef struct call_data {
} call_data; } call_data;
typedef struct channel_data { typedef struct channel_data {
grpc_security_connector *security_connector; grpc_auth_context *auth_context;
grpc_auth_metadata_processor processor; grpc_server_credentials *creds;
grpc_mdctx *mdctx; grpc_mdctx *mdctx;
} channel_data; } channel_data;
@ -160,12 +160,12 @@ static void auth_on_recv(grpc_exec_ctx *exec_ctx, void *user_data,
grpc_stream_op *op = &ops[i]; grpc_stream_op *op = &ops[i];
if (op->type != GRPC_OP_METADATA || calld->got_client_metadata) continue; if (op->type != GRPC_OP_METADATA || calld->got_client_metadata) continue;
calld->got_client_metadata = 1; calld->got_client_metadata = 1;
if (chand->processor.process == NULL) continue; if (chand->creds->processor.process == NULL) continue;
calld->md_op = op; calld->md_op = op;
calld->md = metadata_batch_to_md_array(&op->data.metadata); calld->md = metadata_batch_to_md_array(&op->data.metadata);
chand->processor.process(chand->processor.state, calld->auth_context, chand->creds->processor.process(
calld->md.metadata, calld->md.count, chand->creds->processor.state, calld->auth_context,
on_md_processing_done, elem); calld->md.metadata, calld->md.count, on_md_processing_done, elem);
return; return;
} }
} }
@ -221,7 +221,7 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
} }
server_ctx = grpc_server_security_context_create(); server_ctx = grpc_server_security_context_create();
server_ctx->auth_context = server_ctx->auth_context =
grpc_auth_context_create(chand->security_connector->auth_context); grpc_auth_context_create(chand->auth_context);
server_ctx->auth_context->pollset = initial_op->bind_pollset; server_ctx->auth_context->pollset = initial_op->bind_pollset;
initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx; initial_op->context[GRPC_CONTEXT_SECURITY].value = server_ctx;
initial_op->context[GRPC_CONTEXT_SECURITY].destroy = initial_op->context[GRPC_CONTEXT_SECURITY].destroy =
@ -241,9 +241,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem, grpc_channel *master, grpc_channel_element *elem, grpc_channel *master,
const grpc_channel_args *args, grpc_mdctx *mdctx, const grpc_channel_args *args, grpc_mdctx *mdctx,
int is_first, int is_last) { int is_first, int is_last) {
grpc_security_connector *sc = grpc_find_security_connector_in_args(args); grpc_auth_context *auth_context = grpc_find_auth_context_in_args(args);
grpc_auth_metadata_processor *processor = grpc_server_credentials *creds = grpc_find_server_credentials_in_args(args);
grpc_find_auth_metadata_processor_in_args(args);
/* grab pointers to our data from the channel element */ /* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
@ -252,15 +251,14 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
path */ path */
GPR_ASSERT(!is_first); GPR_ASSERT(!is_first);
GPR_ASSERT(!is_last); GPR_ASSERT(!is_last);
GPR_ASSERT(sc != NULL); GPR_ASSERT(auth_context != NULL);
GPR_ASSERT(processor != NULL); GPR_ASSERT(creds != NULL);
/* initialize members */ /* initialize members */
GPR_ASSERT(!sc->is_client_side); chand->auth_context =
chand->security_connector = GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter"); chand->creds = grpc_server_credentials_ref(creds);
chand->mdctx = mdctx; chand->mdctx = mdctx;
chand->processor = *processor;
} }
/* Destructor for channel data */ /* Destructor for channel data */
@ -268,8 +266,8 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) { grpc_channel_element *elem) {
/* grab pointers to our data from the channel element */ /* grab pointers to our data from the channel element */
channel_data *chand = elem->channel_data; channel_data *chand = elem->channel_data;
GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector, GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter");
"server_auth_filter"); grpc_server_credentials_unref(chand->creds);
} }
const grpc_channel_filter grpc_server_auth_filter = { const grpc_channel_filter grpc_server_auth_filter = {

@ -93,9 +93,9 @@ static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep,
grpc_server_secure_state *state = statep; grpc_server_secure_state *state = statep;
grpc_channel_args *args_copy; grpc_channel_args *args_copy;
grpc_arg args_to_add[2]; grpc_arg args_to_add[2];
args_to_add[0] = grpc_security_connector_to_arg(state->sc); args_to_add[0] = grpc_server_credentials_to_arg(state->creds);
args_to_add[1] = args_to_add[1] =
grpc_auth_metadata_processor_to_arg(&state->creds->processor); grpc_auth_context_to_arg(state->sc->auth_context);
args_copy = grpc_channel_args_copy_and_add( args_copy = grpc_channel_args_copy_and_add(
grpc_server_get_channel_args(state->server), args_to_add, grpc_server_get_channel_args(state->server), args_to_add,
GPR_ARRAY_SIZE(args_to_add)); GPR_ARRAY_SIZE(args_to_add));

@ -75,9 +75,7 @@ grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb) {
return grpc_raw_byte_buffer_create(bb->data.raw.slice_buffer.slices, return grpc_raw_byte_buffer_create(bb->data.raw.slice_buffer.slices,
bb->data.raw.slice_buffer.count); bb->data.raw.slice_buffer.count);
} }
gpr_log(GPR_INFO, "should never get here"); GPR_UNREACHABLE_CODE(return NULL);
abort();
return NULL;
} }
void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) { void grpc_byte_buffer_destroy(grpc_byte_buffer *bb) {
@ -95,7 +93,5 @@ size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) {
case GRPC_BB_RAW: case GRPC_BB_RAW:
return bb->data.raw.slice_buffer.length; return bb->data.raw.slice_buffer.length;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
return 0;
} }

@ -436,8 +436,7 @@ static grpc_cq_completion *allocate_completion(grpc_call *call) {
gpr_mu_unlock(&call->completion_mu); gpr_mu_unlock(&call->completion_mu);
return &call->completions[i]; return &call->completions[i];
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return NULL);
abort();
return NULL; return NULL;
} }
@ -531,9 +530,13 @@ static void set_compression_algorithm(grpc_call *call,
call->compression_algorithm = algo; call->compression_algorithm = algo;
} }
grpc_compression_algorithm grpc_call_get_compression_algorithm( grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
const grpc_call *call) { grpc_call *call) {
return call->compression_algorithm; grpc_compression_algorithm algorithm;
gpr_mu_lock(&call->mu);
algorithm = call->compression_algorithm;
gpr_mu_unlock(&call->mu);
return algorithm;
} }
static void set_encodings_accepted_by_peer( static void set_encodings_accepted_by_peer(
@ -567,12 +570,20 @@ static void set_encodings_accepted_by_peer(
} }
} }
gpr_uint32 grpc_call_get_encodings_accepted_by_peer(grpc_call *call) { gpr_uint32 grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call) {
return call->encodings_accepted_by_peer; gpr_uint32 encodings_accepted_by_peer;
gpr_mu_lock(&call->mu);
encodings_accepted_by_peer = call->encodings_accepted_by_peer;
gpr_mu_unlock(&call->mu);
return encodings_accepted_by_peer;
} }
gpr_uint32 grpc_call_get_message_flags(const grpc_call *call) { gpr_uint32 grpc_call_test_only_get_message_flags(grpc_call *call) {
return call->incoming_message_flags; gpr_uint32 flags;
gpr_mu_lock(&call->mu);
flags = call->incoming_message_flags;
gpr_mu_unlock(&call->mu);
return flags;
} }
static void set_status_details(grpc_call *call, status_source source, static void set_status_details(grpc_call *call, status_source source,

@ -169,17 +169,6 @@ void *grpc_call_context_get(grpc_call *call, grpc_context_index elem);
gpr_uint8 grpc_call_is_client(grpc_call *call); gpr_uint8 grpc_call_is_client(grpc_call *call);
grpc_compression_algorithm grpc_call_get_compression_algorithm(
const grpc_call *call);
gpr_uint32 grpc_call_get_message_flags(const grpc_call *call);
/** Returns a bitset for the encodings (compression algorithms) supported by \a
* call's peer.
*
* To be indexed by grpc_compression_algorithm enum values. */
gpr_uint32 grpc_call_get_encodings_accepted_by_peer(grpc_call *call);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

@ -0,0 +1,65 @@
/*
*
* 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_CORE_SURFACE_CALL_TEST_ONLY_H
#define GRPC_INTERNAL_CORE_SURFACE_CALL_TEST_ONLY_H
#include <grpc/grpc.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Return the compression algorithm from \a call.
*
* \warning This function should \b only be used in test code. */
grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
grpc_call *call);
/** Return the message flags from \a call.
*
* \warning This function should \b only be used in test code. */
gpr_uint32 grpc_call_test_only_get_message_flags(grpc_call *call);
/** Returns a bitset for the encodings (compression algorithms) supported by \a
* call's peer.
*
* To be indexed by grpc_compression_algorithm enum values. */
gpr_uint32 grpc_call_test_only_get_encodings_accepted_by_peer(grpc_call *call);
#ifdef __cplusplus
}
#endif
#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_TEST_ONLY_H */

@ -100,9 +100,7 @@ static void finished_completion(grpc_exec_ctx *exec_ctx, void *pw,
switch (w->phase) { switch (w->phase) {
case WAITING: case WAITING:
case CALLED_BACK: case CALLED_BACK:
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return );
abort();
break;
case CALLING_BACK: case CALLING_BACK:
w->phase = CALLED_BACK; w->phase = CALLED_BACK;
break; break;
@ -149,9 +147,7 @@ static void partly_done(grpc_exec_ctx *exec_ctx, state_watcher *w,
w->phase = CALLING_BACK_AND_FINISHED; w->phase = CALLING_BACK_AND_FINISHED;
break; break;
case CALLING_BACK_AND_FINISHED: case CALLING_BACK_AND_FINISHED:
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return );
abort();
break;
case CALLED_BACK: case CALLED_BACK:
delete = 1; delete = 1;
break; break;

@ -264,8 +264,7 @@ static void del_plucker(grpc_completion_queue *cc, void *tag,
return; return;
} }
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return );
abort();
} }
grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag, grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cc, void *tag,

@ -168,7 +168,5 @@ grpc_chttp2_parse_error grpc_chttp2_data_parser_parse(
} }
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR);
abort();
return GRPC_CHTTP2_CONNECTION_ERROR;
} }

@ -152,9 +152,7 @@ grpc_chttp2_parse_error grpc_chttp2_goaway_parser_parse(
} }
return GRPC_CHTTP2_PARSE_OK; return GRPC_CHTTP2_PARSE_OK;
} }
gpr_log(GPR_ERROR, "Should never end up here"); GPR_UNREACHABLE_CODE(return GRPC_CHTTP2_CONNECTION_ERROR);
abort();
return GRPC_CHTTP2_CONNECTION_ERROR;
} }
void grpc_chttp2_goaway_append(gpr_uint32 last_stream_id, gpr_uint32 error_code, void grpc_chttp2_goaway_append(gpr_uint32 last_stream_id, gpr_uint32 error_code,

@ -1166,9 +1166,7 @@ static int append_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
append_bytes(str, decoded, 3); append_bytes(str, decoded, 3);
goto b64_byte0; goto b64_byte0;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 1);
abort();
return 1;
} }
/* append a null terminator to a string */ /* append a null terminator to a string */
@ -1313,9 +1311,7 @@ static int parse_value_string(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
return 0; return 0;
} }
/* Add code to prevent return without value error */ /* Add code to prevent return without value error */
gpr_log(GPR_ERROR, "Should never reach beyond switch in parse_value_string"); GPR_UNREACHABLE_CODE(return 0);
abort();
return 0;
} }
static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p, static int parse_value_string_with_indexed_key(grpc_chttp2_hpack_parser *p,

@ -422,14 +422,10 @@ int grpc_chttp2_perform_read(grpc_exec_ctx *exec_ctx,
transport_parsing->incoming_frame_size -= (gpr_uint32)(end - cur); transport_parsing->incoming_frame_size -= (gpr_uint32)(end - cur);
return 1; return 1;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
return 0;
} }
static int init_frame_parser(grpc_chttp2_transport_parsing *transport_parsing) { static int init_frame_parser(grpc_chttp2_transport_parsing *transport_parsing) {
@ -585,9 +581,7 @@ static int init_data_frame_parser(
case GRPC_CHTTP2_CONNECTION_ERROR: case GRPC_CHTTP2_CONNECTION_ERROR:
return 0; return 0;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
return 0;
} }
static void free_timeout(void *p) { gpr_free(p); } static void free_timeout(void *p) { gpr_free(p); }
@ -825,7 +819,5 @@ static int parse_frame_slice(grpc_exec_ctx *exec_ctx,
case GRPC_CHTTP2_CONNECTION_ERROR: case GRPC_CHTTP2_CONNECTION_ERROR:
return 0; return 0;
} }
gpr_log(GPR_ERROR, "should never reach here"); GPR_UNREACHABLE_CODE(return 0);
abort();
return 0;
} }

@ -428,7 +428,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c,
emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
return elem; return elem;
} }
abort(); GPR_UNREACHABLE_CODE(return NULL);
} }
indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)]; indices_key = c->indices_keys[HASH_FRAGMENT_3(key_hash)];
@ -442,7 +442,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c,
emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st); emit_lithdr_noidx(c, dynidx(c, indices_key), elem, st);
return elem; return elem;
} }
abort(); GPR_UNREACHABLE_CODE(return NULL);
} }
/* no elem, key in the table... fall back to literal emission */ /* no elem, key in the table... fall back to literal emission */
@ -454,7 +454,7 @@ static grpc_mdelem *hpack_enc(grpc_chttp2_hpack_compressor *c,
emit_lithdr_noidx_v(c, elem, st); emit_lithdr_noidx_v(c, elem, st);
return elem; return elem;
} }
abort(); GPR_UNREACHABLE_CODE(return NULL);
} }
#define STRLEN_LIT(x) (sizeof(x) - 1) #define STRLEN_LIT(x) (sizeof(x) - 1)

@ -153,8 +153,7 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
GPR_ASSERT((*req)->in_flight_); GPR_ASSERT((*req)->in_flight_);
return true; return true;
} }
gpr_log(GPR_ERROR, "Should never reach here"); GPR_UNREACHABLE_CODE(return false);
abort();
} }
void SetupRequest() { cq_ = grpc_completion_queue_create(nullptr); } void SetupRequest() { cq_ = grpc_completion_queue_create(nullptr); }

@ -44,12 +44,14 @@ var GoogleAuth = require('google-auth-library');
var assert = require('assert'); var assert = require('assert');
var AUTH_SCOPE = 'https://www.googleapis.com/auth/xapi.zoo'; var SERVICE_ACCOUNT_EMAIL;
var AUTH_SCOPE_RESPONSE = 'xapi.zoo'; try {
var AUTH_USER = ('155450119199-vefjjaekcc6cmsd5914v6lqufunmh9ue' + SERVICE_ACCOUNT_EMAIL = require(
'@developer.gserviceaccount.com'); process.env.GOOGLE_APPLICATION_CREDENTIALS).client_email;
var COMPUTE_ENGINE_USER = ('155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel' + } catch (e) {
'@developer.gserviceaccount.com'); // This will cause the tests to fail if they need that string
SERVICE_ACCOUNT_EMAIL = null;
}
var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial'; var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin'; var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
@ -345,6 +347,41 @@ function customMetadata(client, done) {
stream.end(); stream.end();
} }
function statusCodeAndMessage(client, done) {
done = multiDone(done, 2);
var arg = {
response_status: {
code: 2,
message: 'test status message'
}
};
client.unaryCall(arg, function(err, resp) {
assert(err);
assert.strictEqual(err.code, 2);
assert.strictEqual(err.message, 'test status message');
done();
});
var duplex = client.fullDuplexCall();
duplex.on('status', function(status) {
assert(status);
assert.strictEqual(status.code, 2);
assert.strictEqual(status.details, 'test status message');
done();
});
duplex.on('error', function(){});
duplex.write(arg);
duplex.end();
}
function unimplementedMethod(client, done) {
client.unimplementedCall({}, function(err, resp) {
assert(err);
assert.strictEqual(err.code, grpc.status.UNIMPLEMENTED);
assert(!err.message);
done();
});
}
/** /**
* Run one of the authentication tests. * Run one of the authentication tests.
* @param {string} expected_user The expected username in the response * @param {string} expected_user The expected username in the response
@ -369,7 +406,7 @@ function authTest(expected_user, scope, client, done) {
assert.strictEqual(resp.payload.body.length, 314159); assert.strictEqual(resp.payload.body.length, 314159);
assert.strictEqual(resp.username, expected_user); assert.strictEqual(resp.username, expected_user);
if (scope) { if (scope) {
assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE); assert(scope.indexOf(resp.oauth_scope) > -1);
} }
if (done) { if (done) {
done(); done();
@ -377,56 +414,49 @@ function authTest(expected_user, scope, client, done) {
}); });
} }
function oauth2Test(expected_user, scope, per_rpc, client, done) { function computeEngineCreds(client, done, extra) {
(new GoogleAuth()).getApplicationDefault(function(err, credential) { authTest(extra.service_account, null, client, done);
}
function serviceAccountCreds(client, done, extra) {
authTest(SERVICE_ACCOUNT_EMAIL, extra.oauth_scope, client, done);
}
function jwtTokenCreds(client, done, extra) {
authTest(SERVICE_ACCOUNT_EMAIL, null, client, done);
}
function oauth2Test(client, done, extra) {
var arg = {
fill_username: true,
fill_oauth_scope: true
};
client.unaryCall(arg, function(err, resp) {
assert.ifError(err); assert.ifError(err);
var arg = { assert.strictEqual(resp.username, SERVICE_ACCOUNT_EMAIL);
fill_username: true, assert(extra.oauth_scope.indexOf(resp.oauth_scope) > -1);
fill_oauth_scope: true if (done) {
}; done();
credential = credential.createScoped(scope); }
credential.getAccessToken(function(err, token) {
assert.ifError(err);
var updateMetadata = function(authURI, metadata, callback) {
metadata.add('authorization', 'Bearer ' + token);
callback(null, metadata);
};
var makeTestCall = function(error, client_metadata) {
assert.ifError(error);
client.unaryCall(arg, function(err, resp) {
assert.ifError(err);
assert.strictEqual(resp.username, expected_user);
assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE);
if (done) {
done();
}
}, client_metadata);
};
if (per_rpc) {
updateMetadata('', new grpc.Metadata(), makeTestCall);
} else {
client.$updateMetadata = updateMetadata;
makeTestCall(null, new grpc.Metadata());
}
});
}); });
} }
function perRpcAuthTest(expected_user, scope, per_rpc, client, done) { function perRpcAuthTest(client, done, extra) {
(new GoogleAuth()).getApplicationDefault(function(err, credential) { (new GoogleAuth()).getApplicationDefault(function(err, credential) {
assert.ifError(err); assert.ifError(err);
var arg = { var arg = {
fill_username: true, fill_username: true,
fill_oauth_scope: true fill_oauth_scope: true
}; };
var scope = extra.oauth_scope;
if (credential.createScopedRequired() && scope) { if (credential.createScopedRequired() && scope) {
credential = credential.createScoped(scope); credential = credential.createScoped(scope);
} }
var creds = grpc.credentials.createFromGoogleCredential(credential); var creds = grpc.credentials.createFromGoogleCredential(credential);
client.unaryCall(arg, function(err, resp) { client.unaryCall(arg, function(err, resp) {
assert.ifError(err); assert.ifError(err);
assert.strictEqual(resp.username, expected_user); assert.strictEqual(resp.username, SERVICE_ACCOUNT_EMAIL);
assert.strictEqual(resp.oauth_scope, AUTH_SCOPE_RESPONSE); assert(extra.oauth_scope.indexOf(resp.oauth_scope) > -1);
if (done) { if (done) {
done(); done();
} }
@ -473,25 +503,44 @@ function getOauth2Creds(scope, callback) {
* Map from test case names to test functions * Map from test case names to test functions
*/ */
var test_cases = { var test_cases = {
empty_unary: {run: emptyUnary}, empty_unary: {run: emptyUnary,
large_unary: {run: largeUnary}, Client: testProto.TestService},
client_streaming: {run: clientStreaming}, large_unary: {run: largeUnary,
server_streaming: {run: serverStreaming}, Client: testProto.TestService},
ping_pong: {run: pingPong}, client_streaming: {run: clientStreaming,
empty_stream: {run: emptyStream}, Client: testProto.TestService},
cancel_after_begin: {run: cancelAfterBegin}, server_streaming: {run: serverStreaming,
cancel_after_first_response: {run: cancelAfterFirstResponse}, Client: testProto.TestService},
timeout_on_sleeping_server: {run: timeoutOnSleepingServer}, ping_pong: {run: pingPong,
custom_metadata: {run: customMetadata}, Client: testProto.TestService},
compute_engine_creds: {run: _.partial(authTest, COMPUTE_ENGINE_USER, null), empty_stream: {run: emptyStream,
getCreds: _.partial(getApplicationCreds, null)}, Client: testProto.TestService},
service_account_creds: {run: _.partial(authTest, AUTH_USER, AUTH_SCOPE), cancel_after_begin: {run: cancelAfterBegin,
getCreds: _.partial(getApplicationCreds, AUTH_SCOPE)}, Client: testProto.TestService},
jwt_token_creds: {run: _.partial(authTest, AUTH_USER, null), cancel_after_first_response: {run: cancelAfterFirstResponse,
getCreds: _.partial(getApplicationCreds, null)}, Client: testProto.TestService},
oauth2_auth_token: {run: _.partial(oauth2Test, AUTH_USER, AUTH_SCOPE, false), timeout_on_sleeping_server: {run: timeoutOnSleepingServer,
getCreds: _.partial(getOauth2Creds, AUTH_SCOPE)}, Client: testProto.TestService},
per_rpc_creds: {run: _.partial(perRpcAuthTest, AUTH_USER, AUTH_SCOPE, true)} custom_metadata: {run: customMetadata,
Client: testProto.TestService},
status_code_and_message: {run: statusCodeAndMessage,
Client: testProto.TestService},
unimplemented_method: {run: unimplementedMethod,
Client: testProto.UnimplementedService},
compute_engine_creds: {run: computeEngineCreds,
Client: testProto.TestService,
getCreds: getApplicationCreds},
service_account_creds: {run: serviceAccountCreds,
Client: testProto.TestService,
getCreds: getApplicationCreds},
jwt_token_creds: {run: jwtTokenCreds,
Client: testProto.TestService,
getCreds: getApplicationCreds},
oauth2_auth_token: {run: oauth2Test,
Client: testProto.TestService,
getCreds: getOauth2Creds},
per_rpc_creds: {run: perRpcAuthTest,
Client: testProto.TestService}
}; };
/** /**
@ -504,8 +553,9 @@ var test_cases = {
* @param {bool} tls Indicates that a secure channel should be used * @param {bool} tls Indicates that a secure channel should be used
* @param {function} done Callback to call when the test is completed. Included * @param {function} done Callback to call when the test is completed. Included
* primarily for use with mocha * primarily for use with mocha
* @param {object=} extra Extra options for some tests
*/ */
function runTest(address, host_override, test_case, tls, test_ca, done) { function runTest(address, host_override, test_case, tls, test_ca, done, extra) {
// TODO(mlumish): enable TLS functionality // TODO(mlumish): enable TLS functionality
var options = {}; var options = {};
var creds; var creds;
@ -529,12 +579,13 @@ function runTest(address, host_override, test_case, tls, test_ca, done) {
var execute = function(err, creds) { var execute = function(err, creds) {
assert.ifError(err); assert.ifError(err);
var client = new testProto.TestService(address, creds, options); var client = new test.Client(address, creds, options);
test.run(client, done); test.run(client, done, extra);
}; };
if (test.getCreds) { if (test.getCreds) {
test.getCreds(function(err, new_creds) { test.getCreds(extra.oauth_scope, function(err, new_creds) {
assert.ifError(err);
execute(err, grpc.credentials.combineChannelCredentials( execute(err, grpc.credentials.combineChannelCredentials(
creds, new_creds)); creds, new_creds));
}); });
@ -547,13 +598,18 @@ if (require.main === module) {
var parseArgs = require('minimist'); var parseArgs = require('minimist');
var argv = parseArgs(process.argv, { var argv = parseArgs(process.argv, {
string: ['server_host', 'server_host_override', 'server_port', 'test_case', string: ['server_host', 'server_host_override', 'server_port', 'test_case',
'use_tls', 'use_test_ca'] 'use_tls', 'use_test_ca', 'default_service_account', 'oauth_scope',
'service_account_key_file']
}); });
var extra_args = {
service_account: argv.default_service_account,
oauth_scope: argv.oauth_scope
};
runTest(argv.server_host + ':' + argv.server_port, argv.server_host_override, runTest(argv.server_host + ':' + argv.server_port, argv.server_host_override,
argv.test_case, argv.use_tls === 'true', argv.use_test_ca === 'true', argv.test_case, argv.use_tls === 'true', argv.use_test_ca === 'true',
function () { function () {
console.log('OK:', argv.test_case); console.log('OK:', argv.test_case);
}); }, extra_args);
} }
/** /**

@ -44,6 +44,9 @@ var testProto = grpc.load({
var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial'; var ECHO_INITIAL_KEY = 'x-grpc-test-echo-initial';
var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin'; var ECHO_TRAILING_KEY = 'x-grpc-test-echo-trailing-bin';
var incompressible_data = fs.readFileSync(
__dirname + '/../../../test/cpp/interop/rnd.dat');
/** /**
* Create a buffer filled with size zeroes * Create a buffer filled with size zeroes
* @param {number} size The length of the buffer * @param {number} size The length of the buffer
@ -83,6 +86,19 @@ function getEchoTrailer(call) {
return response_trailer; return response_trailer;
} }
function getPayload(payload_type, size) {
if (payload_type === 'RANDOM') {
payload_type = ['COMPRESSABLE',
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1];
}
var body;
switch (payload_type) {
case 'COMPRESSABLE': body = zeroBuffer(size); break;
case 'UNCOMPRESSABLE': incompressible_data.slice(size); break;
}
return {type: payload_type, body: body};
}
/** /**
* Respond to an empty parameter with an empty response. * Respond to an empty parameter with an empty response.
* NOTE: this currently does not work due to issue #137 * NOTE: this currently does not work due to issue #137
@ -104,13 +120,14 @@ function handleEmpty(call, callback) {
function handleUnary(call, callback) { function handleUnary(call, callback) {
echoHeader(call); echoHeader(call);
var req = call.request; var req = call.request;
var zeros = zeroBuffer(req.response_size); if (req.response_status) {
var payload_type = req.response_type; var status = req.response_status;
if (payload_type === 'RANDOM') { status.metadata = getEchoTrailer(call);
payload_type = ['COMPRESSABLE', callback(status);
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1]; return;
} }
callback(null, {payload: {type: payload_type, body: zeros}}, var payload = getPayload(req.response_type, req.response_size);
callback(null, {payload: payload},
getEchoTrailer(call)); getEchoTrailer(call));
} }
@ -139,18 +156,14 @@ function handleStreamingInput(call, callback) {
function handleStreamingOutput(call) { function handleStreamingOutput(call) {
echoHeader(call); echoHeader(call);
var req = call.request; var req = call.request;
var payload_type = req.response_type; if (req.response_status) {
if (payload_type === 'RANDOM') { var status = req.response_status;
payload_type = ['COMPRESSABLE', status.metadata = getEchoTrailer(call);
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1]; call.emit('error', status);
return;
} }
_.each(req.response_parameters, function(resp_param) { _.each(req.response_parameters, function(resp_param) {
call.write({ call.write({payload: getPayload(req.response_type, resp_param.size)});
payload: {
body: zeroBuffer(resp_param.size),
type: payload_type
}
});
}); });
call.end(getEchoTrailer(call)); call.end(getEchoTrailer(call));
} }
@ -163,18 +176,14 @@ function handleStreamingOutput(call) {
function handleFullDuplex(call) { function handleFullDuplex(call) {
echoHeader(call); echoHeader(call);
call.on('data', function(value) { call.on('data', function(value) {
var payload_type = value.response_type; if (value.response_status) {
if (payload_type === 'RANDOM') { var status = value.response_status;
payload_type = ['COMPRESSABLE', status.metadata = getEchoTrailer(call);
'UNCOMPRESSABLE'][Math.random() < 0.5 ? 0 : 1]; call.emit('error', status);
return;
} }
_.each(value.response_parameters, function(resp_param) { _.each(value.response_parameters, function(resp_param) {
call.write({ call.write({payload: getPayload(value.response_type, resp_param.size)});
payload: {
body: zeroBuffer(resp_param.size),
type: payload_type
}
});
}); });
}); });
call.on('end', function() { call.on('end', function() {
@ -188,7 +197,7 @@ function handleFullDuplex(call) {
* @param {Call} call Call to handle * @param {Call} call Call to handle
*/ */
function handleHalfDuplex(call) { function handleHalfDuplex(call) {
throw new Error('HalfDuplexCall not yet implemented'); call.emit('error', Error('HalfDuplexCall not yet implemented'));
} }
/** /**

@ -153,7 +153,7 @@ exports.combineCallCredentials = function() {
current = current.compose(arguments[i]); current = current.compose(arguments[i]);
} }
return current; return current;
} };
/** /**
* Create an insecure credentials object. This is used to create a channel that * Create an insecure credentials object. This is used to create a channel that

@ -629,7 +629,7 @@ function Server(options) {
(new Metadata())._getCoreRepresentation(); (new Metadata())._getCoreRepresentation();
batch[grpc.opType.SEND_STATUS_FROM_SERVER] = { batch[grpc.opType.SEND_STATUS_FROM_SERVER] = {
code: grpc.status.UNIMPLEMENTED, code: grpc.status.UNIMPLEMENTED,
details: 'This method is not available on this server.', details: '',
metadata: {} metadata: {}
}; };
batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true; batch[grpc.opType.RECV_CLOSE_ON_SERVER] = true;

@ -57,7 +57,7 @@ describe('Async functionality', function() {
grpc.ServerCredentials.createInsecure()); grpc.ServerCredentials.createInsecure());
server.start(); server.start();
math_client = new math.Math('localhost:' + port_num, math_client = new math.Math('localhost:' + port_num,
grpc.Credentials.createInsecure()); grpc.credentials.createInsecure());
done(); done();
}); });
after(function() { after(function() {

@ -149,7 +149,7 @@ describe('channel', function() {
afterEach(function() { afterEach(function() {
channel.close(); channel.close();
}); });
it.only('should time out if called alone', function(done) { it('should time out if called alone', function(done) {
var old_state = channel.getConnectivityState(); var old_state = channel.getConnectivityState();
var deadline = new Date(); var deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + 1); deadline.setSeconds(deadline.getSeconds() + 1);

@ -130,8 +130,8 @@ describe('client credentials', function() {
callback(null, metadata); callback(null, metadata);
}; };
var creds = grpc.credentials.createFromMetadataGenerator(metadataUpdater); var creds = grpc.credentials.createFromMetadataGenerator(metadataUpdater);
var combined_creds = grpc.credentials.combineCredentials(client_ssl_creds, var combined_creds = grpc.credentials.combineChannelCredentials(
creds); client_ssl_creds, creds);
var client = new Client('localhost:' + port, combined_creds, var client = new Client('localhost:' + port, combined_creds,
client_options); client_options);
var call = client.unary({}, function(err, data) { var call = client.unary({}, function(err, data) {
@ -150,8 +150,8 @@ describe('client credentials', function() {
callback(null, metadata); callback(null, metadata);
}; };
var creds = grpc.credentials.createFromMetadataGenerator(metadataUpdater); var creds = grpc.credentials.createFromMetadataGenerator(metadataUpdater);
var combined_creds = grpc.credentials.combineCredentials(client_ssl_creds, var combined_creds = grpc.credentials.combineChannelCredentials(
creds); client_ssl_creds, creds);
var client = new Client('localhost:' + port, combined_creds, var client = new Client('localhost:' + port, combined_creds,
client_options); client_options);
var call = client.unary({}, function(err, data) { var call = client.unary({}, function(err, data) {
@ -231,7 +231,7 @@ describe('client credentials', function() {
updater_creds, alt_updater_creds); updater_creds, alt_updater_creds);
var call = client.unary({}, function(err, data) { var call = client.unary({}, function(err, data) {
assert.ifError(err); assert.ifError(err);
}, null, {credentials: updater_creds}); }, null, {credentials: combined_updater});
call.on('metadata', function(metadata) { call.on('metadata', function(metadata) {
assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']); assert.deepEqual(metadata.get('plugin_key'), ['plugin_value']);
assert.deepEqual(metadata.get('other_plugin_key'), assert.deepEqual(metadata.get('other_plugin_key'),

@ -71,7 +71,7 @@ describe('Interop tests', function() {
interop_client.runTest(port, name_override, 'server_streaming', true, true, interop_client.runTest(port, name_override, 'server_streaming', true, true,
done); done);
}); });
it('should pass ping_pong', function(done) { it.only('should pass ping_pong', function(done) {
interop_client.runTest(port, name_override, 'ping_pong', true, true, done); interop_client.runTest(port, name_override, 'ping_pong', true, true, done);
}); });
it('should pass empty_stream', function(done) { it('should pass empty_stream', function(done) {
@ -94,4 +94,12 @@ describe('Interop tests', function() {
interop_client.runTest(port, name_override, 'custom_metadata', interop_client.runTest(port, name_override, 'custom_metadata',
true, true, done); true, true, done);
}); });
it('should pass status_code_and_message', function(done) {
interop_client.runTest(port, name_override, 'status_code_and_message',
true, true, done);
});
it('should pass unimplemented_method', function(done) {
interop_client.runTest(port, name_override, 'unimplemented_method',
true, true, done);
});
}); });

@ -250,6 +250,23 @@ function pingPong($stub) {
'Call did not complete successfully'); 'Call did not complete successfully');
} }
/**
* Run the empty_stream test.
* Passes when run against the Node server as of 2015-10-09
* @param $stub Stub object that has service methods.
*/
function emptyStream($stub) {
// for the current PHP implementation, $call->read() will wait
// forever for a server response if the server is not sending any.
// so this test is imeplemented as a timeout to indicate the absence
// of receiving any response from the server
$call = $stub->FullDuplexCall(array('timeout' => 100000));
$call->writesDone();
hardAssert($call->read() === null, 'Server returned too many responses');
hardAssert($call->getStatus()->code === Grpc\STATUS_OK,
'Call did not complete successfully');
}
/** /**
* Run the cancel_after_begin test. * Run the cancel_after_begin test.
* Passes when run against the Node server as of 2015-08-28 * Passes when run against the Node server as of 2015-08-28
@ -370,6 +387,9 @@ switch ($args['test_case']) {
case 'ping_pong': case 'ping_pong':
pingPong($stub); pingPong($stub);
break; break;
case 'empty_stream':
emptyStream($stub);
break;
case 'cancel_after_begin': case 'cancel_after_begin':
cancelAfterBegin($stub); cancelAfterBegin($stub);
break; break;

@ -1,7 +1,7 @@
%YAML 1.2 %YAML 1.2
--- | --- |
# GRPC gyp file # GRPC Node gyp file
# This currently builds C code. # This currently builds the Node extension and dependencies
# This file has been automatically generated from a template file. # This file has been automatically generated from a template file.
# Please look at the templates directory instead. # Please look at the templates directory instead.
# This file can be regenerated from the template by running # This file can be regenerated from the template by running
@ -39,54 +39,24 @@
# Some of this file is built with the help of # Some of this file is built with the help of
# https://n8.io/converting-a-c-library-to-gyp/ # https://n8.io/converting-a-c-library-to-gyp/
{ {
'variables': {
'config': '<!(echo $CONFIG)'
},
# TODO: Finish windows support # TODO: Finish windows support
'target_defaults': { 'target_defaults': {
'default_configuration': 'Debug', # Empirically, Node only exports ALPN symbols if its major version is >0.
'configurations': { # io.js always reports versions >0 and always exports ALPN symbols.
'Debug': { # Therefore, Node's major version will be truthy if and only if it
'defines': [ 'DEBUG', '_DEBUG' ], # supports ALPN. The output of "node -v" is v[major].[minor].[patch],
'msvs_settings': { # like "v4.1.1" in a recent version. We use grep to extract just the
'VCCLCompilerTool': { # major version. "4", would be the output for the example.
'RuntimeLibrary': 1, # static debug
},
},
},
'Release': {
'defines': [ 'NDEBUG' ],
'msvs_settings': {
'VCCLCompilerTool': {
'RuntimeLibrary': 0, # static release
},
},
}
},
'msvs_settings': {
'VCLinkerTool': {
'GenerateDebugInformation': 'true',
},
},
# TODO: Add fallback for Windows, and if pkg-config is not available
'defines': [ 'defines': [
'TSI_OPENSSL_ALPN_SUPPORT=<!(pkg-config --atleast-version=1.0.2 openssl >/dev/null 2>&1 && echo 1 || echo 0)' 'TSI_OPENSSL_ALPN_SUPPORT=<!(node -v | grep -oP "(?<=v)(\d+)(?=\.\d+\.\d+)")'
], ],
'include_dirs': [ 'include_dirs': [
'.', '.',
'include' 'include'
], ]
# TODO: Check for libraries with pkg-config
'libraries': [
'-lcrypto',
'-lssl',
'-ldl',
'-lpthread',
'-lz'
],
'direct_dependent_settings': {
'include_dirs': [
'.',
'include'
],
}
}, },
'targets': [ 'targets': [
% for lib in libs: % for lib in libs:
@ -108,5 +78,65 @@
}, },
% endif % endif
% endfor % endfor
{
'include_dirs': [
"<!(node -e \"require('nan')\")"
],
'cflags': [
'-std=c++0x',
'-Wall',
'-pthread',
'-g',
'-zdefs',
'-Werror',
'-Wno-error=deprecated-declarations'
],
'ldflags': [
'-g'
],
"conditions": [
['OS != "win"', {
'conditions': [
['config=="gcov"', {
'cflags': [
'-ftest-coverage',
'-fprofile-arcs',
'-O0'
],
'ldflags': [
'-ftest-coverage',
'-fprofile-arcs'
]
}
]
]
}],
['OS == "mac"', {
'xcode_settings': {
'MACOSX_DEPLOYMENT_TARGET': '10.9',
'OTHER_CFLAGS': [
'-std=c++11',
'-stdlib=libc++'
]
}
}]
],
"target_name": "grpc_node",
"sources": [
"src/node/ext/byte_buffer.cc",
"src/node/ext/call.cc",
"src/node/ext/call_credentials.cc",
"src/node/ext/channel.cc",
"src/node/ext/channel_credentials.cc",
"src/node/ext/completion_queue_async_worker.cc",
"src/node/ext/node_grpc.cc",
"src/node/ext/server.cc",
"src/node/ext/server_credentials.cc",
"src/node/ext/timeval.cc"
],
"dependencies": [
"grpc"
]
}
] ]
} }

@ -46,7 +46,7 @@
#include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/cq_verifier.h"
#include "src/core/channel/channel_args.h" #include "src/core/channel/channel_args.h"
#include "src/core/channel/compress_filter.h" #include "src/core/channel/compress_filter.h"
#include "src/core/surface/call.h" #include "src/core/surface/call_test_only.h"
enum { TIMEOUT = 200000 }; enum { TIMEOUT = 200000 };
@ -196,12 +196,13 @@ static void request_with_payload_template(
cq_expect_completion(cqv, tag(101), 1); cq_expect_completion(cqv, tag(101), 1);
cq_verify(cqv); cq_verify(cqv);
GPR_ASSERT(GPR_BITCOUNT(grpc_call_get_encodings_accepted_by_peer(s)) == 3); GPR_ASSERT(
GPR_ASSERT(GPR_BITGET(grpc_call_get_encodings_accepted_by_peer(s), GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer(s)) == 3);
GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
GRPC_COMPRESS_NONE) != 0); GRPC_COMPRESS_NONE) != 0);
GPR_ASSERT(GPR_BITGET(grpc_call_get_encodings_accepted_by_peer(s), GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
GRPC_COMPRESS_DEFLATE) != 0); GRPC_COMPRESS_DEFLATE) != 0);
GPR_ASSERT(GPR_BITGET(grpc_call_get_encodings_accepted_by_peer(s), GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
GRPC_COMPRESS_GZIP) != 0); GRPC_COMPRESS_GZIP) != 0);
op = ops; op = ops;

@ -38,7 +38,7 @@
#include <grpc++/channel.h> #include <grpc++/channel.h>
#include "src/core/surface/call.h" #include "src/core/surface/call_test_only.h"
namespace grpc { namespace grpc {
namespace testing { namespace testing {
@ -57,11 +57,11 @@ class InteropClientContextInspector {
// Inspector methods, able to peek inside ClientContext, follow. // Inspector methods, able to peek inside ClientContext, follow.
grpc_compression_algorithm GetCallCompressionAlgorithm() const { grpc_compression_algorithm GetCallCompressionAlgorithm() const {
return grpc_call_get_compression_algorithm(context_.call_); return grpc_call_test_only_get_compression_algorithm(context_.call_);
} }
gpr_uint32 GetMessageFlags() const { gpr_uint32 GetMessageFlags() const {
return grpc_call_get_message_flags(context_.call_); return grpc_call_test_only_get_message_flags(context_.call_);
} }
private: private:

@ -38,7 +38,7 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <grpc++/security/server_credentials.h> #include <grpc++/security/server_credentials.h>
#include "src/core/surface/call.h" #include "src/core/surface/call_test_only.h"
#include "test/core/end2end/data/ssl_test_data.h" #include "test/core/end2end/data/ssl_test_data.h"
DECLARE_bool(use_tls); DECLARE_bool(use_tls);
@ -65,11 +65,11 @@ InteropServerContextInspector::InteropServerContextInspector(
grpc_compression_algorithm grpc_compression_algorithm
InteropServerContextInspector::GetCallCompressionAlgorithm() const { InteropServerContextInspector::GetCallCompressionAlgorithm() const {
return grpc_call_get_compression_algorithm(context_.call_); return grpc_call_test_only_get_compression_algorithm(context_.call_);
} }
gpr_uint32 InteropServerContextInspector::GetEncodingsAcceptedByClient() const { gpr_uint32 InteropServerContextInspector::GetEncodingsAcceptedByClient() const {
return grpc_call_get_encodings_accepted_by_peer(context_.call_); return grpc_call_test_only_get_encodings_accepted_by_peer(context_.call_);
} }
std::shared_ptr<const AuthContext> std::shared_ptr<const AuthContext>

@ -82,9 +82,12 @@ static deque<string> get_hosts(const string& name) {
namespace runsc { namespace runsc {
// ClientContext allocator // ClientContext allocator
static ClientContext* AllocContext(list<ClientContext>* contexts) { template <class T>
static ClientContext* AllocContext(list<ClientContext>* contexts, T deadline) {
contexts->emplace_back(); contexts->emplace_back();
return &contexts->back(); auto context = &contexts->back();
context->set_deadline(deadline);
return context;
} }
struct ServerData { struct ServerData {
@ -147,6 +150,11 @@ std::unique_ptr<ScenarioResult> RunScenario(
// Trim to just what we need // Trim to just what we need
workers.resize(num_clients + num_servers); workers.resize(num_clients + num_servers);
gpr_timespec deadline =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_seconds(
warmup_seconds + benchmark_seconds + 20, GPR_TIMESPAN));
// Start servers // Start servers
using runsc::ServerData; using runsc::ServerData;
// servers is array rather than std::vector to avoid gcc-4.4 issues // servers is array rather than std::vector to avoid gcc-4.4 issues
@ -160,7 +168,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
result_server_config.set_host(workers[i]); result_server_config.set_host(workers[i]);
*args.mutable_setup() = server_config; *args.mutable_setup() = server_config;
servers[i].stream = servers[i].stream =
servers[i].stub->RunServer(runsc::AllocContext(&contexts)); servers[i].stub->RunServer(runsc::AllocContext(&contexts, deadline));
GPR_ASSERT(servers[i].stream->Write(args)); GPR_ASSERT(servers[i].stream->Write(args));
ServerStatus init_status; ServerStatus init_status;
GPR_ASSERT(servers[i].stream->Read(&init_status)); GPR_ASSERT(servers[i].stream->Read(&init_status));
@ -188,7 +196,7 @@ std::unique_ptr<ScenarioResult> RunScenario(
result_client_config.set_host(workers[i + num_servers]); result_client_config.set_host(workers[i + num_servers]);
*args.mutable_setup() = client_config; *args.mutable_setup() = client_config;
clients[i].stream = clients[i].stream =
clients[i].stub->RunTest(runsc::AllocContext(&contexts)); clients[i].stub->RunTest(runsc::AllocContext(&contexts, deadline));
GPR_ASSERT(clients[i].stream->Write(args)); GPR_ASSERT(clients[i].stream->Write(args));
ClientStatus init_status; ClientStatus init_status;
GPR_ASSERT(clients[i].stream->Read(&init_status)); GPR_ASSERT(clients[i].stream->Read(&init_status));

@ -857,6 +857,7 @@ src/core/statistics/census_rpc_stats.h \
src/core/surface/api_trace.h \ src/core/surface/api_trace.h \
src/core/surface/byte_buffer_queue.h \ src/core/surface/byte_buffer_queue.h \
src/core/surface/call.h \ src/core/surface/call.h \
src/core/surface/call_test_only.h \
src/core/surface/channel.h \ src/core/surface/channel.h \
src/core/surface/completion_queue.h \ src/core/surface/completion_queue.h \
src/core/surface/event_string.h \ src/core/surface/event_string.h \

@ -53,8 +53,8 @@ DOCKER_IMAGE_NAME=grpc_jenkins_slave${docker_suffix}_`sha1sum tools/jenkins/grpc
# Make sure docker image has been built. Should be instantaneous if so. # Make sure docker image has been built. Should be instantaneous if so.
docker build -t $DOCKER_IMAGE_NAME tools/jenkins/grpc_jenkins_slave$docker_suffix docker build -t $DOCKER_IMAGE_NAME tools/jenkins/grpc_jenkins_slave$docker_suffix
# Make sure the CID file is gone. # Choose random name for docker container
rm -f docker.cid CONTAINER_NAME="run_tests_$(uuidgen)"
# Run tests inside docker # Run tests inside docker
docker run \ docker run \
@ -70,23 +70,21 @@ docker run \
-v /var/run/docker.sock:/var/run/docker.sock \ -v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/bin/docker \ -v $(which docker):/bin/docker \
-w /var/local/git/grpc \ -w /var/local/git/grpc \
--cidfile=docker.cid \ --name=$CONTAINER_NAME \
$DOCKER_IMAGE_NAME \ $DOCKER_IMAGE_NAME \
bash -l /var/local/jenkins/grpc/tools/jenkins/docker_run_tests.sh || DOCKER_FAILED="true" bash -l /var/local/jenkins/grpc/tools/jenkins/docker_run_tests.sh || DOCKER_FAILED="true"
DOCKER_CID=`cat docker.cid`
if [ "$XML_REPORT" != "" ] if [ "$XML_REPORT" != "" ]
then then
docker cp "$DOCKER_CID:/var/local/git/grpc/$XML_REPORT" $git_root docker cp "$CONTAINER_NAME:/var/local/git/grpc/$XML_REPORT" $git_root
fi fi
docker cp "$DOCKER_CID:/var/local/git/grpc/reports.zip" $git_root || true docker cp "$CONTAINER_NAME:/var/local/git/grpc/reports.zip" $git_root || true
unzip $git_root/reports.zip -d $git_root || true unzip $git_root/reports.zip -d $git_root || true
rm -f reports.zip rm -f reports.zip
# remove the container, possibly killing it first # remove the container, possibly killing it first
docker rm -f $DOCKER_CID || true docker rm -f $CONTAINER_NAME || true
if [ "$DOCKER_FAILED" != "" ] && [ "$XML_REPORT" == "" ] if [ "$DOCKER_FAILED" != "" ] && [ "$XML_REPORT" == "" ]
then then

@ -77,7 +77,7 @@ docker build -t $BASE_IMAGE --force-rm=true tools/jenkins/$BASE_NAME || exit $?
# Create a local branch so the child Docker script won't complain # Create a local branch so the child Docker script won't complain
git branch -f jenkins-docker git branch -f jenkins-docker
CIDFILE=`mktemp -u --suffix=.cid` CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)"
# Prepare image for interop tests, commit it on success. # Prepare image for interop tests, commit it on success.
(docker run \ (docker run \
@ -85,17 +85,14 @@ CIDFILE=`mktemp -u --suffix=.cid`
-i $TTY_FLAG \ -i $TTY_FLAG \
$MOUNT_ARGS \ $MOUNT_ARGS \
-v /tmp/ccache:/tmp/ccache \ -v /tmp/ccache:/tmp/ccache \
--cidfile=$CIDFILE \ --name=$CONTAINER_NAME \
$BASE_IMAGE \ $BASE_IMAGE \
bash -l /var/local/jenkins/grpc/tools/jenkins/$BASE_NAME/build_interop.sh \ bash -l /var/local/jenkins/grpc/tools/jenkins/$BASE_NAME/build_interop.sh \
&& docker commit `cat $CIDFILE` $INTEROP_IMAGE \ && docker commit $CONTAINER_NAME $INTEROP_IMAGE \
&& echo "Successfully built image $INTEROP_IMAGE") && echo "Successfully built image $INTEROP_IMAGE")
EXITCODE=$? EXITCODE=$?
# remove intermediate container, possibly killing it first # remove intermediate container, possibly killing it first
docker rm -f `cat $CIDFILE` docker rm -f $CONTAINER_NAME
# remove the cidfile
rm -rf `cat $CIDFILE`
exit $EXITCODE exit $EXITCODE

@ -48,6 +48,7 @@ RUN apt-get update && apt-get install -y \
libc6-dbg \ libc6-dbg \
libc6-dev \ libc6-dev \
libgtest-dev \ libgtest-dev \
libssl-dev \
libtool \ libtool \
make \ make \
strace \ strace \

@ -45,5 +45,4 @@ make install-certs
# build Node interop client & server # build Node interop client & server
npm install -g node-gyp npm install -g node-gyp
make install_c -C /var/local/git/grpc (npm install && node-gyp rebuild)
(cd src/node && npm install && node-gyp rebuild)

@ -157,6 +157,12 @@ RUN apt-get update && apt-get install -y \
RUN apt-get install -y libzookeeper-mt-dev RUN apt-get install -y libzookeeper-mt-dev
##################
# Docker "inception".
# Note this is quite the ugly hack.
# This makes sure that the docker binary we inject has its dependencies.
RUN curl https://get.docker.com/ | sh
RUN apt-get remove --purge -y docker-engine
RUN mkdir /var/local/jenkins RUN mkdir /var/local/jenkins

@ -38,24 +38,32 @@ import subprocess
_DEVNULL = open(os.devnull, 'w') _DEVNULL = open(os.devnull, 'w')
def wait_for_file(filepath, timeout_seconds=15):
"""Wait until given file exists and returns its content.""" def random_name(base_name):
started = time.time() """Randomizes given base name."""
while time.time() - started < timeout_seconds: return '%s_%s' % (base_name, uuid.uuid4())
if os.path.isfile(filepath):
with open(filepath, 'r') as f:
content = f.read() def docker_kill(cid):
# make sure we don't return empty content """Kills a docker container. Returns True if successful."""
if content: return subprocess.call(['docker','kill', str(cid)],
return content stdout=_DEVNULL,
time.sleep(1) stderr=subprocess.STDOUT) == 0
raise Exception('Failed to read file %s.' % filepath)
def docker_mapped_port(cid, port): def docker_mapped_port(cid, port, timeout_seconds=15):
"""Get port mapped to internal given internal port for given container.""" """Get port mapped to internal given internal port for given container."""
output = subprocess.check_output('docker port %s %s' % (cid, port), shell=True) started = time.time()
return int(output.split(':', 2)[1]) while time.time() - started < timeout_seconds:
try:
output = subprocess.check_output('docker port %s %s' % (cid, port),
stderr=_DEVNULL,
shell=True)
return int(output.split(':', 2)[1])
except subprocess.CalledProcessError as e:
pass
raise Exception('Failed to get exposed port %s for container %s.' %
(port, cid))
def finish_jobs(jobs): def finish_jobs(jobs):
@ -71,7 +79,7 @@ def image_exists(image):
"""Returns True if given docker image exists.""" """Returns True if given docker image exists."""
return subprocess.call(['docker','inspect', image], return subprocess.call(['docker','inspect', image],
stdout=_DEVNULL, stdout=_DEVNULL,
stderr=_DEVNULL) == 0 stderr=subprocess.STDOUT) == 0
def remove_image(image, skip_nonexistent=False, max_retries=10): def remove_image(image, skip_nonexistent=False, max_retries=10):
@ -79,7 +87,9 @@ def remove_image(image, skip_nonexistent=False, max_retries=10):
if skip_nonexistent and not image_exists(image): if skip_nonexistent and not image_exists(image):
return True return True
for attempt in range(0, max_retries): for attempt in range(0, max_retries):
if subprocess.call(['docker','rmi', '-f', image]) == 0: if subprocess.call(['docker','rmi', '-f', image],
stdout=_DEVNULL,
stderr=subprocess.STDOUT) == 0:
return True return True
time.sleep(2) time.sleep(2)
print 'Failed to remove docker image %s' % image print 'Failed to remove docker image %s' % image
@ -92,23 +102,16 @@ class DockerJob:
def __init__(self, spec): def __init__(self, spec):
self._spec = spec self._spec = spec
self._job = jobset.Job(spec, bin_hash=None, newline_on_success=True, travis=True, add_env={}, xml_report=None) self._job = jobset.Job(spec, bin_hash=None, newline_on_success=True, travis=True, add_env={}, xml_report=None)
self._cidfile = spec.cidfile self._container_name = spec.container_name
self._cid = None
def cid(self):
"""Gets cid of this container"""
if not self._cid:
self._cid = wait_for_file(self._cidfile)
return self._cid
def mapped_port(self, port): def mapped_port(self, port):
return docker_mapped_port(self.cid(), port) return docker_mapped_port(self._container_name, port)
def kill(self, suppress_failure=False): def kill(self, suppress_failure=False):
"""Sends kill signal to the container.""" """Sends kill signal to the container."""
if suppress_failure: if suppress_failure:
self._job.suppress_failure_message() self._job.suppress_failure_message()
return subprocess.call(['docker','kill', self.cid()]) == 0 return docker_kill(self._container_name)
def is_running(self): def is_running(self):
"""Polls a job and returns True if given job is still running.""" """Polls a job and returns True if given job is still running."""

@ -135,13 +135,14 @@ class JobSpec(object):
def __init__(self, cmdline, shortname=None, environ=None, hash_targets=None, def __init__(self, cmdline, shortname=None, environ=None, hash_targets=None,
cwd=None, shell=False, timeout_seconds=5*60, flake_retries=0, cwd=None, shell=False, timeout_seconds=5*60, flake_retries=0,
timeout_retries=0): timeout_retries=0, kill_handler=None):
""" """
Arguments: Arguments:
cmdline: a list of arguments to pass as the command line cmdline: a list of arguments to pass as the command line
environ: a dictionary of environment variables to set in the child process environ: a dictionary of environment variables to set in the child process
hash_targets: which files to include in the hash representing the jobs version hash_targets: which files to include in the hash representing the jobs version
(or empty, indicating the job should not be hashed) (or empty, indicating the job should not be hashed)
kill_handler: a handler that will be called whenever job.kill() is invoked
""" """
if environ is None: if environ is None:
environ = {} environ = {}
@ -156,6 +157,7 @@ class JobSpec(object):
self.timeout_seconds = timeout_seconds self.timeout_seconds = timeout_seconds
self.flake_retries = flake_retries self.flake_retries = flake_retries
self.timeout_retries = timeout_retries self.timeout_retries = timeout_retries
self.kill_handler = kill_handler
def identity(self): def identity(self):
return '%r %r %r' % (self.cmdline, self.environ, self.hash_targets) return '%r %r %r' % (self.cmdline, self.environ, self.hash_targets)
@ -254,6 +256,8 @@ class Job(object):
def kill(self): def kill(self):
if self._state == _RUNNING: if self._state == _RUNNING:
self._state = _KILLED self._state = _KILLED
if self._spec.kill_handler:
self._spec.kill_handler(self)
self._process.terminate() self._process.terminate()
def suppress_failure_message(self): def suppress_failure_message(self):

@ -71,6 +71,7 @@ class CXXLanguage:
self.client_cmdline_base = ['bins/opt/interop_client'] self.client_cmdline_base = ['bins/opt/interop_client']
self.client_cwd = None self.client_cwd = None
self.server_cwd = None self.server_cwd = None
self.safename = 'cxx'
def cloud_to_prod_args(self): def cloud_to_prod_args(self):
return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS +
@ -96,6 +97,7 @@ class CSharpLanguage:
self.client_cmdline_base = ['mono', 'Grpc.IntegrationTesting.Client.exe'] self.client_cmdline_base = ['mono', 'Grpc.IntegrationTesting.Client.exe']
self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug' self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug'
self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug' self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug'
self.safename = str(self)
def cloud_to_prod_args(self): def cloud_to_prod_args(self):
return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS +
@ -121,6 +123,7 @@ class JavaLanguage:
self.client_cmdline_base = ['./run-test-client.sh'] self.client_cmdline_base = ['./run-test-client.sh']
self.client_cwd = '../grpc-java' self.client_cwd = '../grpc-java'
self.server_cwd = '../grpc-java' self.server_cwd = '../grpc-java'
self.safename = str(self)
def cloud_to_prod_args(self): def cloud_to_prod_args(self):
return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS +
@ -147,6 +150,7 @@ class GoLanguage:
# TODO: this relies on running inside docker # TODO: this relies on running inside docker
self.client_cwd = '/go/src/google.golang.org/grpc/interop/client' self.client_cwd = '/go/src/google.golang.org/grpc/interop/client'
self.server_cwd = '/go/src/google.golang.org/grpc/interop/server' self.server_cwd = '/go/src/google.golang.org/grpc/interop/server'
self.safename = str(self)
def cloud_to_prod_args(self): def cloud_to_prod_args(self):
return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS +
@ -172,6 +176,7 @@ class NodeLanguage:
self.client_cmdline_base = ['node', 'src/node/interop/interop_client.js'] self.client_cmdline_base = ['node', 'src/node/interop/interop_client.js']
self.client_cwd = None self.client_cwd = None
self.server_cwd = None self.server_cwd = None
self.safename = str(self)
def cloud_to_prod_args(self): def cloud_to_prod_args(self):
return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS +
@ -196,6 +201,7 @@ class PHPLanguage:
def __init__(self): def __init__(self):
self.client_cmdline_base = ['src/php/bin/interop_client.sh'] self.client_cmdline_base = ['src/php/bin/interop_client.sh']
self.client_cwd = None self.client_cwd = None
self.safename = str(self)
def cloud_to_prod_args(self): def cloud_to_prod_args(self):
return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS +
@ -218,6 +224,7 @@ class RubyLanguage:
self.client_cmdline_base = ['ruby', 'src/ruby/bin/interop/interop_client.rb'] self.client_cmdline_base = ['ruby', 'src/ruby/bin/interop/interop_client.rb']
self.client_cwd = None self.client_cwd = None
self.server_cwd = None self.server_cwd = None
self.safename = str(self)
def cloud_to_prod_args(self): def cloud_to_prod_args(self):
return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS + return (self.client_cmdline_base + _CLOUD_TO_PROD_BASE_ARGS +
@ -251,11 +258,9 @@ _LANGUAGES = {
# languages supported as cloud_to_cloud servers # languages supported as cloud_to_cloud servers
_SERVERS = ['c++', 'node', 'csharp', 'java', 'go', 'ruby'] _SERVERS = ['c++', 'node', 'csharp', 'java', 'go', 'ruby']
# TODO(jtattermusch): add empty_stream once PHP starts supporting it.
# TODO(jtattermusch): add timeout_on_sleeping_server once java starts supporting it. # TODO(jtattermusch): add timeout_on_sleeping_server once java starts supporting it.
# TODO(jtattermusch): add support for auth tests.
_TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong', _TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong',
'client_streaming', 'server_streaming', 'empty_stream', 'client_streaming', 'server_streaming',
'cancel_after_begin', 'cancel_after_first_response'] 'cancel_after_begin', 'cancel_after_first_response']
_AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds', _AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds',
@ -321,17 +326,29 @@ def add_auth_options(language, test_case, cmdline, env):
return (cmdline, env) return (cmdline, env)
def _job_kill_handler(job):
if job._spec.container_name:
dockerjob.docker_kill(job._spec.container_name)
def cloud_to_prod_jobspec(language, test_case, docker_image=None, auth=False): def cloud_to_prod_jobspec(language, test_case, docker_image=None, auth=False):
"""Creates jobspec for cloud-to-prod interop test""" """Creates jobspec for cloud-to-prod interop test"""
cmdline = language.cloud_to_prod_args() + ['--test_case=%s' % test_case] cmdline = language.cloud_to_prod_args() + ['--test_case=%s' % test_case]
cwd = language.client_cwd cwd = language.client_cwd
environ = language.cloud_to_prod_env() environ = language.cloud_to_prod_env()
container_name = None
if auth: if auth:
cmdline, environ = add_auth_options(language, test_case, cmdline, environ) cmdline, environ = add_auth_options(language, test_case, cmdline, environ)
cmdline = bash_login_cmdline(cmdline) cmdline = bash_login_cmdline(cmdline)
if docker_image: if docker_image:
cmdline = docker_run_cmdline(cmdline, image=docker_image, cwd=cwd, environ=environ) container_name = dockerjob.random_name('interop_client_%s' % language.safename)
cmdline = docker_run_cmdline(cmdline,
image=docker_image,
cwd=cwd,
environ=environ,
docker_args=['--net=host',
'--name', container_name])
cwd = None cwd = None
environ = None environ = None
@ -343,7 +360,9 @@ def cloud_to_prod_jobspec(language, test_case, docker_image=None, auth=False):
shortname="%s:%s:%s" % (suite_name, language, test_case), shortname="%s:%s:%s" % (suite_name, language, test_case),
timeout_seconds=2*60, timeout_seconds=2*60,
flake_retries=5 if args.allow_flakes else 0, flake_retries=5 if args.allow_flakes else 0,
timeout_retries=2 if args.allow_flakes else 0) timeout_retries=2 if args.allow_flakes else 0,
kill_handler=_job_kill_handler)
test_job.container_name = container_name
return test_job return test_job
@ -356,11 +375,14 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
'--server_port=%s' % server_port ]) '--server_port=%s' % server_port ])
cwd = language.client_cwd cwd = language.client_cwd
if docker_image: if docker_image:
container_name = dockerjob.random_name('interop_client_%s' % language.safename)
cmdline = docker_run_cmdline(cmdline, cmdline = docker_run_cmdline(cmdline,
image=docker_image, image=docker_image,
cwd=cwd, cwd=cwd,
docker_args=['--net=host']) docker_args=['--net=host',
'--name', container_name])
cwd = None cwd = None
test_job = jobset.JobSpec( test_job = jobset.JobSpec(
cmdline=cmdline, cmdline=cmdline,
cwd=cwd, cwd=cwd,
@ -368,34 +390,36 @@ def cloud_to_cloud_jobspec(language, test_case, server_name, server_host,
test_case), test_case),
timeout_seconds=2*60, timeout_seconds=2*60,
flake_retries=5 if args.allow_flakes else 0, flake_retries=5 if args.allow_flakes else 0,
timeout_retries=2 if args.allow_flakes else 0) timeout_retries=2 if args.allow_flakes else 0,
kill_handler=_job_kill_handler)
test_job.container_name = container_name
return test_job return test_job
def server_jobspec(language, docker_image): def server_jobspec(language, docker_image):
"""Create jobspec for running a server""" """Create jobspec for running a server"""
cidfile = tempfile.mktemp() container_name = dockerjob.random_name('interop_server_%s' % language.safename)
cmdline = bash_login_cmdline(language.server_args() + cmdline = bash_login_cmdline(language.server_args() +
['--port=%s' % _DEFAULT_SERVER_PORT]) ['--port=%s' % _DEFAULT_SERVER_PORT])
docker_cmdline = docker_run_cmdline(cmdline, docker_cmdline = docker_run_cmdline(cmdline,
image=docker_image, image=docker_image,
cwd=language.server_cwd, cwd=language.server_cwd,
docker_args=['-p', str(_DEFAULT_SERVER_PORT), docker_args=['-p', str(_DEFAULT_SERVER_PORT),
'--cidfile', cidfile]) '--name', container_name])
server_job = jobset.JobSpec( server_job = jobset.JobSpec(
cmdline=docker_cmdline, cmdline=docker_cmdline,
shortname="interop_server:%s" % language, shortname="interop_server_%s" % language,
timeout_seconds=30*60) timeout_seconds=30*60)
server_job.cidfile = cidfile server_job.container_name = container_name
return server_job return server_job
def build_interop_image_jobspec(language, tag=None): def build_interop_image_jobspec(language, tag=None):
"""Creates jobspec for building interop docker image for a language""" """Creates jobspec for building interop docker image for a language"""
safelang = str(language).replace("+", "x")
if not tag: if not tag:
tag = 'grpc_interop_%s:%s' % (safelang, uuid.uuid4()) tag = 'grpc_interop_%s:%s' % (language.safename, uuid.uuid4())
env = {'INTEROP_IMAGE': tag, 'BASE_NAME': 'grpc_interop_%s' % safelang} env = {'INTEROP_IMAGE': tag,
'BASE_NAME': 'grpc_interop_%s' % language.safename}
if not args.travis: if not args.travis:
env['TTY_FLAG'] = '-t' env['TTY_FLAG'] = '-t'
build_job = jobset.JobSpec( build_job = jobset.JobSpec(

@ -46,6 +46,8 @@ then
lcov --base-directory . --directory . -c -o coverage.info lcov --base-directory . --directory . -c -o coverage.info
genhtml -o ../reports/node_ext_coverage --num-spaces 2 \ genhtml -o ../reports/node_ext_coverage --num-spaces 2 \
-t 'Node gRPC test coverage' coverage.info -t 'Node gRPC test coverage' coverage.info
echo '<html><head><meta http-equiv="refresh" content="0;URL=lcov-report/index.html"></head></html>' > \
../reports/node_coverage/index.html
else else
./node_modules/mocha/bin/mocha --timeout 8000 src/node/test ./node_modules/mocha/bin/mocha --timeout 8000 src/node/test
fi fi

@ -101,7 +101,8 @@ class SimpleConfig(object):
timeout_seconds=self.timeout_seconds, timeout_seconds=self.timeout_seconds,
hash_targets=hash_targets hash_targets=hash_targets
if self.allow_hashing else None, if self.allow_hashing else None,
flake_retries=5 if args.allow_flakes else 0) flake_retries=5 if args.allow_flakes else 0,
timeout_retries=3 if args.allow_flakes else 0)
# ValgrindConfig: compile with some CONFIG=config, but use valgrind to run # ValgrindConfig: compile with some CONFIG=config, but use valgrind to run
@ -121,7 +122,7 @@ class ValgrindConfig(object):
shortname='valgrind %s' % cmdline[0], shortname='valgrind %s' % cmdline[0],
hash_targets=None, hash_targets=None,
flake_retries=5 if args.allow_flakes else 0, flake_retries=5 if args.allow_flakes else 0,
timeout_retries=2 if args.allow_flakes else 0) timeout_retries=3 if args.allow_flakes else 0)
def get_c_tests(travis, test_lang) : def get_c_tests(travis, test_lang) :

@ -12369,6 +12369,7 @@
"src/core/surface/api_trace.h", "src/core/surface/api_trace.h",
"src/core/surface/byte_buffer_queue.h", "src/core/surface/byte_buffer_queue.h",
"src/core/surface/call.h", "src/core/surface/call.h",
"src/core/surface/call_test_only.h",
"src/core/surface/channel.h", "src/core/surface/channel.h",
"src/core/surface/completion_queue.h", "src/core/surface/completion_queue.h",
"src/core/surface/event_string.h", "src/core/surface/event_string.h",
@ -12608,6 +12609,7 @@
"src/core/surface/call.h", "src/core/surface/call.h",
"src/core/surface/call_details.c", "src/core/surface/call_details.c",
"src/core/surface/call_log_batch.c", "src/core/surface/call_log_batch.c",
"src/core/surface/call_test_only.h",
"src/core/surface/channel.c", "src/core/surface/channel.c",
"src/core/surface/channel.h", "src/core/surface/channel.h",
"src/core/surface/channel_connectivity.c", "src/core/surface/channel_connectivity.c",
@ -12861,6 +12863,7 @@
"src/core/surface/api_trace.h", "src/core/surface/api_trace.h",
"src/core/surface/byte_buffer_queue.h", "src/core/surface/byte_buffer_queue.h",
"src/core/surface/call.h", "src/core/surface/call.h",
"src/core/surface/call_test_only.h",
"src/core/surface/channel.h", "src/core/surface/channel.h",
"src/core/surface/completion_queue.h", "src/core/surface/completion_queue.h",
"src/core/surface/event_string.h", "src/core/surface/event_string.h",
@ -13070,6 +13073,7 @@
"src/core/surface/call.h", "src/core/surface/call.h",
"src/core/surface/call_details.c", "src/core/surface/call_details.c",
"src/core/surface/call_log_batch.c", "src/core/surface/call_log_batch.c",
"src/core/surface/call_test_only.h",
"src/core/surface/channel.c", "src/core/surface/channel.c",
"src/core/surface/channel.h", "src/core/surface/channel.h",
"src/core/surface/channel_connectivity.c", "src/core/surface/channel_connectivity.c",

@ -343,6 +343,7 @@
<ClInclude Include="..\..\..\src\core\surface\api_trace.h" /> <ClInclude Include="..\..\..\src\core\surface\api_trace.h" />
<ClInclude Include="..\..\..\src\core\surface\byte_buffer_queue.h" /> <ClInclude Include="..\..\..\src\core\surface\byte_buffer_queue.h" />
<ClInclude Include="..\..\..\src\core\surface\call.h" /> <ClInclude Include="..\..\..\src\core\surface\call.h" />
<ClInclude Include="..\..\..\src\core\surface\call_test_only.h" />
<ClInclude Include="..\..\..\src\core\surface\channel.h" /> <ClInclude Include="..\..\..\src\core\surface\channel.h" />
<ClInclude Include="..\..\..\src\core\surface\completion_queue.h" /> <ClInclude Include="..\..\..\src\core\surface\completion_queue.h" />
<ClInclude Include="..\..\..\src\core\surface\event_string.h" /> <ClInclude Include="..\..\..\src\core\surface\event_string.h" />

@ -734,6 +734,9 @@
<ClInclude Include="..\..\..\src\core\surface\call.h"> <ClInclude Include="..\..\..\src\core\surface\call.h">
<Filter>src\core\surface</Filter> <Filter>src\core\surface</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\core\surface\call_test_only.h">
<Filter>src\core\surface</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\core\surface\channel.h"> <ClInclude Include="..\..\..\src\core\surface\channel.h">
<Filter>src\core\surface</Filter> <Filter>src\core\surface</Filter>
</ClInclude> </ClInclude>

@ -322,6 +322,7 @@
<ClInclude Include="..\..\..\src\core\surface\api_trace.h" /> <ClInclude Include="..\..\..\src\core\surface\api_trace.h" />
<ClInclude Include="..\..\..\src\core\surface\byte_buffer_queue.h" /> <ClInclude Include="..\..\..\src\core\surface\byte_buffer_queue.h" />
<ClInclude Include="..\..\..\src\core\surface\call.h" /> <ClInclude Include="..\..\..\src\core\surface\call.h" />
<ClInclude Include="..\..\..\src\core\surface\call_test_only.h" />
<ClInclude Include="..\..\..\src\core\surface\channel.h" /> <ClInclude Include="..\..\..\src\core\surface\channel.h" />
<ClInclude Include="..\..\..\src\core\surface\completion_queue.h" /> <ClInclude Include="..\..\..\src\core\surface\completion_queue.h" />
<ClInclude Include="..\..\..\src\core\surface\event_string.h" /> <ClInclude Include="..\..\..\src\core\surface\event_string.h" />

@ -632,6 +632,9 @@
<ClInclude Include="..\..\..\src\core\surface\call.h"> <ClInclude Include="..\..\..\src\core\surface\call.h">
<Filter>src\core\surface</Filter> <Filter>src\core\surface</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\src\core\surface\call_test_only.h">
<Filter>src\core\surface</Filter>
</ClInclude>
<ClInclude Include="..\..\..\src\core\surface\channel.h"> <ClInclude Include="..\..\..\src\core\surface\channel.h">
<Filter>src\core\surface</Filter> <Filter>src\core\surface</Filter>
</ClInclude> </ClInclude>

Loading…
Cancel
Save