Merge github.com:grpc/grpc into nudiff

pull/10048/head
Craig Tiller 8 years ago
commit 77bcd5a58a
  1. 24
      .pylintrc
  2. 64
      CMakeLists.txt
  3. 80
      Makefile
  4. 21
      bazel/cc_grpc_library.bzl
  5. 3
      bazel/grpc_build_system.bzl
  6. 24
      build.yaml
  7. 2
      composer.json
  8. 2
      doc/PROTOCOL-WEB.md
  9. 60
      doc/server_side_auth.md
  10. 2
      examples/php/composer.json
  11. 2
      gRPC-Core.podspec
  12. 44
      package.xml
  13. 4
      src/compiler/cpp_generator.cc
  14. 2
      src/core/ext/client_channel/client_channel_plugin.c
  15. 10
      src/core/ext/client_channel/http_proxy.c
  16. 28
      src/core/ext/client_channel/parse_address.c
  17. 22
      src/core/ext/client_channel/resolver_registry.c
  18. 5
      src/core/ext/client_channel/resolver_registry.h
  19. 11
      src/core/ext/client_channel/subchannel.c
  20. 3
      src/core/ext/client_channel/subchannel.h
  21. 37
      src/core/ext/client_channel/uri_parser.c
  22. 4
      src/core/ext/client_channel/uri_parser.h
  23. 2
      src/core/ext/lb_policy/grpclb/grpclb.c
  24. 2
      src/core/ext/transport/chttp2/client/chttp2_connector.c
  25. 3
      src/core/ext/transport/chttp2/client/insecure/channel_create.c
  26. 7
      src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
  27. 4
      src/core/lib/http/parser.c
  28. 12
      src/core/lib/iomgr/sockaddr_utils.c
  29. 8
      src/core/lib/support/sync.c
  30. 4
      src/core/lib/surface/call.c
  31. 35
      src/core/lib/transport/transport.c
  32. 6
      src/core/lib/transport/transport.h
  33. 2
      src/core/lib/tsi/test_creds/BUILD
  34. 4
      src/cpp/server/health/default_health_check_service.cc
  35. 2
      src/php/README.md
  36. 2
      src/php/composer.json
  37. 26
      src/python/grpcio/grpc/__init__.py
  38. 24
      src/python/grpcio/grpc/_auth.py
  39. 17
      src/python/grpcio/grpc/_channel.py
  40. 12
      src/python/grpcio/grpc/_common.py
  41. 6
      src/python/grpcio/grpc/_plugin_wrapping.py
  42. 22
      src/python/grpcio/grpc/_server.py
  43. 5
      src/python/grpcio/grpc/beta/_client_adaptations.py
  44. 159
      src/python/grpcio/grpc/beta/_connectivity_channel.py
  45. 18
      src/python/grpcio/grpc/beta/_server_adaptations.py
  46. 9
      src/python/grpcio/grpc/beta/implementations.py
  47. 2
      src/python/grpcio/grpc/framework/foundation/logging_pool.py
  48. 2
      src/python/grpcio_tests/tests/http2/negative_http2_client.py
  49. 2
      templates/composer.json.template
  50. 2
      templates/gRPC-Core.podspec.template
  51. 44
      templates/package.xml.template
  52. 2
      templates/src/php/composer.json.template
  53. 2
      test/core/census/BUILD
  54. 2
      test/core/channel/BUILD
  55. 116
      test/core/client_channel/parse_address_test.c
  56. 2
      test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
  57. 4
      test/core/client_channel/resolvers/dns_resolver_test.c
  58. 4
      test/core/client_channel/resolvers/sockaddr_resolver_test.c
  59. 5
      test/core/client_channel/uri_fuzzer_test.c
  60. 23
      test/core/client_channel/uri_parser_test.c
  61. 2
      test/core/compression/BUILD
  62. BIN
      test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448
  63. 2
      test/core/handshake/BUILD
  64. 16
      test/core/iomgr/sockaddr_utils_test.c
  65. 33
      test/core/iomgr/tcp_server_posix_test.c
  66. 1
      test/core/slice/percent_encoding_test.c
  67. 2
      test/core/support/BUILD
  68. 2
      test/core/surface/BUILD
  69. 7
      test/core/transport/BUILD
  70. 58
      test/core/transport/stream_owned_slice_test.c
  71. 3
      test/core/util/BUILD
  72. 52
      test/core/util/port.c
  73. 256
      test/core/util/port_posix.c
  74. 10
      test/core/util/port_server_client.c
  75. 7
      test/core/util/port_server_client.h
  76. 247
      test/core/util/port_windows.c
  77. 2
      test/cpp/codegen/compiler_test_golden
  78. 102
      test/cpp/interop/http2_client.cc
  79. 3
      test/cpp/interop/http2_client.h
  80. 45
      test/cpp/microbenchmarks/bm_call_create.cc
  81. 15
      test/cpp/microbenchmarks/bm_metadata.cc
  82. 3
      tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh
  83. 1
      tools/doxygen/Doxyfile.c++
  84. 1
      tools/doxygen/Doxyfile.c++.internal
  85. 1
      tools/doxygen/Doxyfile.core
  86. 1
      tools/doxygen/Doxyfile.core.internal
  87. 2
      tools/gce/linux_performance_worker_init.sh
  88. 17
      tools/internal_ci/windows/grpc_master.bat
  89. 73
      tools/jenkins/run_full_performance_released.sh
  90. 138
      tools/profiling/microbenchmarks/bm2bq.py
  91. 5
      tools/profiling/microbenchmarks/bm_json.py
  92. 38
      tools/run_tests/generated/sources_and_headers.json
  93. 66
      tools/run_tests/generated/tests.json
  94. 11
      tools/run_tests/performance/scenario_config.py
  95. 15
      tools/run_tests/python_utils/start_port_server.py
  96. 6
      tools/run_tests/run_interop_tests.py
  97. 15
      tools/run_tests/run_microbenchmark.py
  98. 17
      tools/run_tests/run_tests.py
  99. 3
      tools/run_tests/run_tests_matrix.py
  100. 46
      tools/run_tests/start_port_server.py
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,3 +1,14 @@
[VARIABLES]
# TODO(https://github.com/PyCQA/pylint/issues/1345): How does the inspection
# not include "unused_" and "ignored_" by default?
dummy-variables-rgx=^ignored_|^unused_
[MISCELLANEOUS]
# NOTE(nathaniel): We are big fans of "TODO(<issue link>): " and
# "NOTE(<username or issue link>): ". We do not allow "TODO:",
# "TODO(<username>):", "FIXME:", or anything else.
notes=FIXME,XXX
[MESSAGES CONTROL]
#TODO: Enable missing-docstring
@ -11,15 +22,11 @@
#TODO: Enable protected-access
#TODO: Enable no-name-in-module
#TODO: Enable unused-argument
#TODO: Enable fixme
#TODO: Enable wrong-import-order
#TODO: Enable no-value-for-parameter
#TODO: Enable cyclic-import
#TODO: Enable unused-variable
#TODO: Enable redefined-outer-name
#TODO: Enable unused-import
# TODO(https://github.com/PyCQA/pylint/issues/59#issuecomment-283774279):
# enable cyclic-import after a 1.7-or-later pylint release that recognizes our
# disable=cyclic-import suppressions.
#TODO: Enable too-many-instance-attributes
#TODO: Enable broad-except
#TODO: Enable too-many-locals
#TODO: Enable too-many-lines
#TODO: Enable redefined-variable-type
@ -29,6 +36,5 @@
#TODO: Enable too-many-return-statements
#TODO: Enable too-many-nested-blocks
#TODO: Enable super-init-not-called
#TODO: Enable no-self-use
disable=missing-docstring,too-few-public-methods,too-many-arguments,no-init,duplicate-code,invalid-name,suppressed-message,locally-disabled,protected-access,no-name-in-module,unused-argument,fixme,wrong-import-order,no-value-for-parameter,cyclic-import,unused-variable,redefined-outer-name,unused-import,too-many-instance-attributes,broad-except,too-many-locals,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-return-statements,too-many-nested-blocks,super-init-not-called,no-self-use
disable=missing-docstring,too-few-public-methods,too-many-arguments,no-init,duplicate-code,invalid-name,suppressed-message,locally-disabled,protected-access,no-name-in-module,unused-argument,wrong-import-order,cyclic-import,too-many-instance-attributes,too-many-locals,too-many-lines,redefined-variable-type,next-method-called,import-error,useless-else-on-loop,too-many-return-statements,too-many-nested-blocks,super-init-not-called

@ -440,6 +440,7 @@ add_dependencies(buildtests_c mlog_test)
add_dependencies(buildtests_c multiple_server_queues_test)
add_dependencies(buildtests_c murmur_hash_test)
add_dependencies(buildtests_c no_server_test)
add_dependencies(buildtests_c parse_address_test)
add_dependencies(buildtests_c percent_encoding_test)
if(_gRPC_PLATFORM_LINUX)
add_dependencies(buildtests_c pollset_set_test)
@ -464,6 +465,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c socket_utils_test)
endif()
add_dependencies(buildtests_c status_conversion_test)
add_dependencies(buildtests_c stream_owned_slice_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c tcp_client_posix_test)
endif()
@ -1447,10 +1449,8 @@ add_library(grpc_test_util
test/core/util/mock_endpoint.c
test/core/util/parse_hexstring.c
test/core/util/passthru_endpoint.c
test/core/util/port_posix.c
test/core/util/port.c
test/core/util/port_server_client.c
test/core/util/port_uv.c
test/core/util/port_windows.c
test/core/util/slice_splitter.c
test/core/util/trickle_endpoint.c
src/core/lib/channel/channel_args.c
@ -1656,10 +1656,8 @@ add_library(grpc_test_util_unsecure
test/core/util/mock_endpoint.c
test/core/util/parse_hexstring.c
test/core/util/passthru_endpoint.c
test/core/util/port_posix.c
test/core/util/port.c
test/core/util/port_server_client.c
test/core/util/port_uv.c
test/core/util/port_windows.c
test/core/util/slice_splitter.c
test/core/util/trickle_endpoint.c
)
@ -6443,6 +6441,33 @@ target_link_libraries(no_server_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(parse_address_test
test/core/client_channel/parse_address_test.c
)
target_include_directories(parse_address_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(parse_address_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(percent_encoding_test
test/core/slice/percent_encoding_test.c
)
@ -6933,6 +6958,33 @@ target_link_libraries(status_conversion_test
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
add_executable(stream_owned_slice_test
test/core/transport/stream_owned_slice_test.c
)
target_include_directories(stream_owned_slice_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${BORINGSSL_ROOT_DIR}/include
PRIVATE ${PROTOBUF_ROOT_DIR}/src
PRIVATE ${BENCHMARK_ROOT_DIR}/include
PRIVATE ${ZLIB_ROOT_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include
)
target_link_libraries(stream_owned_slice_test
${_gRPC_ALLTARGETS_LIBRARIES}
grpc_test_util
grpc
gpr_test_util
gpr
)
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)

@ -1002,6 +1002,7 @@ murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test
nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test
nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test
no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
parse_address_test: $(BINDIR)/$(CONFIG)/parse_address_test
percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
percent_encoding_test: $(BINDIR)/$(CONFIG)/percent_encoding_test
@ -1024,6 +1025,7 @@ sockaddr_utils_test: $(BINDIR)/$(CONFIG)/sockaddr_utils_test
socket_utils_test: $(BINDIR)/$(CONFIG)/socket_utils_test
ssl_server_fuzzer: $(BINDIR)/$(CONFIG)/ssl_server_fuzzer
status_conversion_test: $(BINDIR)/$(CONFIG)/status_conversion_test
stream_owned_slice_test: $(BINDIR)/$(CONFIG)/stream_owned_slice_test
tcp_client_posix_test: $(BINDIR)/$(CONFIG)/tcp_client_posix_test
tcp_client_uv_test: $(BINDIR)/$(CONFIG)/tcp_client_uv_test
tcp_posix_test: $(BINDIR)/$(CONFIG)/tcp_posix_test
@ -1360,6 +1362,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/multiple_server_queues_test \
$(BINDIR)/$(CONFIG)/murmur_hash_test \
$(BINDIR)/$(CONFIG)/no_server_test \
$(BINDIR)/$(CONFIG)/parse_address_test \
$(BINDIR)/$(CONFIG)/percent_encoding_test \
$(BINDIR)/$(CONFIG)/pollset_set_test \
$(BINDIR)/$(CONFIG)/resolve_address_posix_test \
@ -1378,6 +1381,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/sockaddr_utils_test \
$(BINDIR)/$(CONFIG)/socket_utils_test \
$(BINDIR)/$(CONFIG)/status_conversion_test \
$(BINDIR)/$(CONFIG)/stream_owned_slice_test \
$(BINDIR)/$(CONFIG)/tcp_client_posix_test \
$(BINDIR)/$(CONFIG)/tcp_client_uv_test \
$(BINDIR)/$(CONFIG)/tcp_posix_test \
@ -1793,6 +1797,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/murmur_hash_test || ( echo test murmur_hash_test failed ; exit 1 )
$(E) "[RUN] Testing no_server_test"
$(Q) $(BINDIR)/$(CONFIG)/no_server_test || ( echo test no_server_test failed ; exit 1 )
$(E) "[RUN] Testing parse_address_test"
$(Q) $(BINDIR)/$(CONFIG)/parse_address_test || ( echo test parse_address_test failed ; exit 1 )
$(E) "[RUN] Testing percent_encoding_test"
$(Q) $(BINDIR)/$(CONFIG)/percent_encoding_test || ( echo test percent_encoding_test failed ; exit 1 )
$(E) "[RUN] Testing pollset_set_test"
@ -1829,6 +1835,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/socket_utils_test || ( echo test socket_utils_test failed ; exit 1 )
$(E) "[RUN] Testing status_conversion_test"
$(Q) $(BINDIR)/$(CONFIG)/status_conversion_test || ( echo test status_conversion_test failed ; exit 1 )
$(E) "[RUN] Testing stream_owned_slice_test"
$(Q) $(BINDIR)/$(CONFIG)/stream_owned_slice_test || ( echo test stream_owned_slice_test failed ; exit 1 )
$(E) "[RUN] Testing tcp_client_posix_test"
$(Q) $(BINDIR)/$(CONFIG)/tcp_client_posix_test || ( echo test tcp_client_posix_test failed ; exit 1 )
$(E) "[RUN] Testing tcp_client_uv_test"
@ -3319,10 +3327,8 @@ LIBGRPC_TEST_UTIL_SRC = \
test/core/util/mock_endpoint.c \
test/core/util/parse_hexstring.c \
test/core/util/passthru_endpoint.c \
test/core/util/port_posix.c \
test/core/util/port.c \
test/core/util/port_server_client.c \
test/core/util/port_uv.c \
test/core/util/port_windows.c \
test/core/util/slice_splitter.c \
test/core/util/trickle_endpoint.c \
src/core/lib/channel/channel_args.c \
@ -3521,10 +3527,8 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
test/core/util/mock_endpoint.c \
test/core/util/parse_hexstring.c \
test/core/util/passthru_endpoint.c \
test/core/util/port_posix.c \
test/core/util/port.c \
test/core/util/port_server_client.c \
test/core/util/port_uv.c \
test/core/util/port_windows.c \
test/core/util/slice_splitter.c \
test/core/util/trickle_endpoint.c \
@ -11083,6 +11087,38 @@ endif
endif
PARSE_ADDRESS_TEST_SRC = \
test/core/client_channel/parse_address_test.c \
PARSE_ADDRESS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PARSE_ADDRESS_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/parse_address_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/parse_address_test: $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(PARSE_ADDRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/parse_address_test
endif
$(OBJDIR)/$(CONFIG)/test/core/client_channel/parse_address_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_parse_address_test: $(PARSE_ADDRESS_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(PARSE_ADDRESS_TEST_OBJS:.o=.dep)
endif
endif
PERCENT_DECODE_FUZZER_SRC = \
test/core/slice/percent_decode_fuzzer.c \
@ -11787,6 +11823,38 @@ endif
endif
STREAM_OWNED_SLICE_TEST_SRC = \
test/core/transport/stream_owned_slice_test.c \
STREAM_OWNED_SLICE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STREAM_OWNED_SLICE_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/stream_owned_slice_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(STREAM_OWNED_SLICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/stream_owned_slice_test
endif
$(OBJDIR)/$(CONFIG)/test/core/transport/stream_owned_slice_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
deps_stream_owned_slice_test: $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(STREAM_OWNED_SLICE_TEST_OBJS:.o=.dep)
endif
endif
TCP_CLIENT_POSIX_TEST_SRC = \
test/core/iomgr/tcp_client_posix_test.c \

@ -2,7 +2,7 @@
load("//:bazel/generate_cc.bzl", "generate_cc")
def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
def cc_grpc_library(name, srcs, deps, proto_only, use_external = False, **kwargs):
"""Generates C++ grpc classes from a .proto file.
Assumes the generated classes will be used in cc_api_version = 2.
@ -12,6 +12,8 @@ def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
srcs: a single proto_library, which wraps the .proto files with services.
deps: a list of C++ proto_library (or cc_proto_library) which provides
the compiled code of any message that the services depend on.
use_external: When True the grpc deps are prefixed with //external. This
allows grpc to be used as a dependency in other bazel projects.
**kwargs: rest of arguments, e.g., compatible_with and visibility.
"""
if len(srcs) > 1:
@ -37,18 +39,31 @@ def cc_grpc_library(name, srcs, deps, proto_only, **kwargs):
)
if not proto_only:
if use_external:
# when this file is used by non-grpc projects
plugin = "//external:grpc_cpp_plugin"
else:
plugin = "//:grpc_cpp_plugin"
generate_cc(
name = codegen_grpc_target,
srcs = [proto_target],
plugin = "//:grpc_cpp_plugin",
plugin = plugin,
**kwargs
)
if use_external:
# when this file is used by non-grpc projects
grpc_deps = ["//external:grpc++", "//external:grpc++_codegen_proto",
"//external:protobuf"]
else:
grpc_deps = ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"]
native.cc_library(
name = name,
srcs = [":" + codegen_grpc_target, ":" + codegen_target],
hdrs = [":" + codegen_grpc_target, ":" + codegen_target],
deps = deps + ["//:grpc++", "//:grpc++_codegen_proto", "//external:protobuf"],
deps = deps + grpc_deps,
**kwargs
)
else:

@ -58,11 +58,12 @@ def grpc_proto_plugin(name, srcs = [], deps = []):
load("//:bazel/cc_grpc_library.bzl", "cc_grpc_library")
def grpc_proto_library(name, srcs = [], deps = [], well_known_deps = [], has_services = True):
def grpc_proto_library(name, srcs = [], deps = [], well_known_deps = [], has_services = True, use_external = False):
cc_grpc_library(
name = name,
srcs = srcs,
deps = deps,
proto_only = not has_services,
use_external = use_external,
)

@ -611,10 +611,8 @@ filegroups:
- test/core/util/mock_endpoint.c
- test/core/util/parse_hexstring.c
- test/core/util/passthru_endpoint.c
- test/core/util/port_posix.c
- test/core/util/port.c
- test/core/util/port_server_client.c
- test/core/util/port_uv.c
- test/core/util/port_windows.c
- test/core/util/slice_splitter.c
- test/core/util/trickle_endpoint.c
deps:
@ -2494,6 +2492,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: parse_address_test
build: test
language: c
src:
- test/core/client_channel/parse_address_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: percent_decode_fuzzer
build: fuzzer
language: c
@ -2750,6 +2758,16 @@ targets:
- grpc
- gpr_test_util
- gpr
- name: stream_owned_slice_test
build: test
language: c
src:
- test/core/transport/stream_owned_slice_test.c
deps:
- grpc_test_util
- grpc
- gpr_test_util
- gpr
- name: tcp_client_posix_test
cpu_cost: 0.5
build: test

@ -7,7 +7,7 @@
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -94,8 +94,6 @@ the response stream needs to be text encoded e.g. when XHR is used or due
to security policies with XHR
* Accept: application/grpc-web-text
2. The default text encoding is base64
* Text encoding may be specified with Content-Type or Accept headers as
* application/grpc-web-text-base64
* Note that “Content-Transfer-Encoding: base64” should not be used.
Due to in-stream base64 padding when delimiting messages, the entire
response body is not necessarily a valid base64-encoded entity

@ -0,0 +1,60 @@
Server-side API for Authenticating Clients
==========================================
NOTE: This document describes how server-side authentication works in C-core based gRPC implementations only. In gRPC Java and Go, server side authentication is handled differently.
## AuthContext
To perform server-side authentication, gRPC exposes the *authentication context* for each call. The context exposes important authentication-related information about the RPC such as the type of security/authentication type being used and the peer identity.
The authentication context is structured as a multi-map of key-value pairs - the *auth properties*. In addition to that, for authenticated RPCs, the set of properties corresponding to a selected key will represent the verified identity of the caller - the *peer identity*.
The contents of the *auth properties* are populated by an *auth interceptor*. The interceptor also chooses which property key will act as the peer identity (e.g. for client certificate authentication this property will be `"x509_common_name"` or `"x509_subject_alternative_name"`).
WARNING: AuthContext is the only reliable source of truth when it comes to authenticating RPCs. Using any other call/context properties for authentication purposes is wrong and inherently unsafe.
####Example AuthContext contents
For secure channel using mutual TLS authentication with both client and server certificates (test certificates from this repository are used).
Populated auth properties:
```
"transport_security_type": "ssl" # connection is secured using TLS/SSL
"x509_common_name": "*.test.google.com" # from client's certificate
"x509_pem_cert": "-----BEGIN CERTIFICATE-----\n..." # client's PEM encoded certificate
"x509_subject_alternative_name": "*.test.google.fr"
"x509_subject_alternative_name": "waterzooi.test.google.be"
"x509_subject_alternative_name": "*.test.youtube.com"
"x509_subject_alternative_name": "192.168.1.3"
```
The peer identity is set of all properties named `"x509_subject_alternative_name"`:
```
peer_identity_property_name = "x509_subject_alternative_name"
```
## AuthProperty
Auth properties are elements of the AuthContext. They have a name (a key of type string) and a value which can be a string or binary data.
## Auth Interceptors
Auth interceptors are gRPC components that populate contents of the auth context based on gRPC's internal state and/or call metadata.
gRPC comes with some basic "interceptors" already built-in.
WARNING: While there is a public API that allows anyone to write their own custom interceptor, please think twice before using it.
There are legitimate uses for custom interceptors but you should keep in mind that as auth interceptors essentially decide which RPCs are authenticated and which are not, their code is very sensitive from the security perspective and getting things wrong might have serious consequences. If unsure, we strongly recommend to rely on official & proven interceptors that come with gRPC.
####Available auth interceptors
- TLS/SSL certificate authentication (built into gRPC's security layer, automatically used whenever you use a secure connection)
- (coming soon) JWT auth token authentication
- more will be added over time
## Status (by language)
C-core exposes low level API to access auth context contents and to implement an auth interceptor.
In C++, the auth interceptor API is exposed as `AuthMetadataProcessor`.
A high level API to access AuthContext contents is available in these languages:
- C++
- C# (implementation in-progress)
- other languages coming soon

@ -2,7 +2,7 @@
"name": "grpc/grpc-demo",
"description": "gRPC example for PHP",
"require": {
"grpc/grpc": "v1.1.0"
"grpc/grpc": "^v1.1.0"
},
"autoload": {
"psr-4": {

@ -917,7 +917,7 @@ Pod::Spec.new do |s|
'test/core/util/debugger_macros.c',
'test/core/util/test_config.{c,h}',
'test/core/util/port.h',
'test/core/util/port_posix.c',
'test/core/util/port.c',
'test/core/util/port_server_client.{c,h}'
end
end

@ -10,7 +10,7 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
<date>2017-01-13</date>
<date>2017-03-01</date>
<time>16:06:07</time>
<version>
<release>1.2.0dev</release>
@ -22,8 +22,8 @@
</stability>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@ -1276,8 +1276,8 @@ Update to wrap gRPC C Core version 0.10.0
</release>
<release>
<version>
<release>1.1.0dev</release>
<api>1.1.0dev</api>
<release>1.1.0RC1</release>
<api>1.1.0RC1</api>
</version>
<stability>
<release>beta</release>
@ -1287,7 +1287,39 @@ Update to wrap gRPC C Core version 0.10.0
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2017-01-31</date>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.2.0RC1</release>
<api>1.2.0RC1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2017-03-01</date>
<license>BSD</license>
<notes>
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
</release>
</changelog>

@ -102,7 +102,7 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
vars["filename_base"] = file->filename_without_ext();
vars["message_header_ext"] = file->message_header_ext();
printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n");
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
printer->Print(vars,
"// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n");
@ -1010,7 +1010,7 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
vars["message_header_ext"] = file->message_header_ext();
vars["service_header_ext"] = file->service_header_ext();
printer->Print(vars, "// Generated by the gRPC protobuf plugin.\n");
printer->Print(vars, "// Generated by the gRPC C++ plugin.\n");
printer->Print(vars,
"// If you make any local change, they will be lost.\n");
printer->Print(vars, "// source: $filename$\n\n");

@ -64,7 +64,7 @@ static bool set_default_host_if_unset(grpc_exec_ctx *exec_ctx,
}
}
char *default_authority = grpc_get_default_authority(
grpc_channel_stack_builder_get_target(builder));
exec_ctx, grpc_channel_stack_builder_get_target(builder));
if (default_authority != NULL) {
grpc_arg arg;
arg.type = GRPC_ARG_STRING;

@ -46,10 +46,11 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/support/env.h"
static char* grpc_get_http_proxy_server() {
static char* grpc_get_http_proxy_server(grpc_exec_ctx* exec_ctx) {
char* uri_str = gpr_getenv("http_proxy");
if (uri_str == NULL) return NULL;
grpc_uri* uri = grpc_uri_parse(uri_str, false /* suppress_errors */);
grpc_uri* uri =
grpc_uri_parse(exec_ctx, uri_str, false /* suppress_errors */);
char* proxy_name = NULL;
if (uri == NULL || uri->authority == NULL) {
gpr_log(GPR_ERROR, "cannot parse value of 'http_proxy' env var");
@ -76,9 +77,10 @@ static bool proxy_mapper_map_name(grpc_exec_ctx* exec_ctx,
const grpc_channel_args* args,
char** name_to_resolve,
grpc_channel_args** new_args) {
*name_to_resolve = grpc_get_http_proxy_server();
*name_to_resolve = grpc_get_http_proxy_server(exec_ctx);
if (*name_to_resolve == NULL) return false;
grpc_uri* uri = grpc_uri_parse(server_uri, false /* suppress_errors */);
grpc_uri* uri =
grpc_uri_parse(exec_ctx, server_uri, false /* suppress_errors */);
if (uri == NULL || uri->path[0] == '\0') {
gpr_log(GPR_ERROR,
"'http_proxy' environment variable set, but cannot "

@ -44,6 +44,7 @@
#include <grpc/support/host_port.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/support/string.h"
#ifdef GRPC_HAVE_UNIX_SOCKET
@ -120,9 +121,30 @@ int parse_ipv6(grpc_uri *uri, grpc_resolved_address *resolved_addr) {
memset(in6, 0, sizeof(*in6));
resolved_addr->len = sizeof(*in6);
in6->sin6_family = AF_INET6;
if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
goto done;
/* Handle the RFC6874 syntax for IPv6 zone identifiers. */
char *host_end = (char *)gpr_memrchr(host, '%', strlen(host));
if (host_end != NULL) {
GPR_ASSERT(host_end >= host);
char host_without_scope[INET6_ADDRSTRLEN];
size_t host_without_scope_len = (size_t)(host_end - host);
strncpy(host_without_scope, host, host_without_scope_len);
host_without_scope[host_without_scope_len] = '\0';
if (inet_pton(AF_INET6, host_without_scope, &in6->sin6_addr) == 0) {
gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host_without_scope);
goto done;
}
if (gpr_parse_bytes_to_uint32(host_end + 1,
strlen(host) - host_without_scope_len - 1,
&in6->sin6_scope_id) == 0) {
gpr_log(GPR_ERROR, "invalid ipv6 scope id: '%s'", host_end + 1);
goto done;
}
} else {
if (inet_pton(AF_INET6, host, &in6->sin6_addr) == 0) {
gpr_log(GPR_ERROR, "invalid ipv6 address: '%s'", host);
goto done;
}
}
if (port != NULL) {

@ -108,22 +108,23 @@ static grpc_resolver_factory *lookup_factory_by_uri(grpc_uri *uri) {
return lookup_factory(uri->scheme);
}
static grpc_resolver_factory *resolve_factory(const char *target,
static grpc_resolver_factory *resolve_factory(grpc_exec_ctx *exec_ctx,
const char *target,
grpc_uri **uri,
char **canonical_target) {
grpc_resolver_factory *factory = NULL;
GPR_ASSERT(uri != NULL);
*uri = grpc_uri_parse(target, 1);
*uri = grpc_uri_parse(exec_ctx, target, 1);
factory = lookup_factory_by_uri(*uri);
if (factory == NULL) {
grpc_uri_destroy(*uri);
gpr_asprintf(canonical_target, "%s%s", g_default_resolver_prefix, target);
*uri = grpc_uri_parse(*canonical_target, 1);
*uri = grpc_uri_parse(exec_ctx, *canonical_target, 1);
factory = lookup_factory_by_uri(*uri);
if (factory == NULL) {
grpc_uri_destroy(grpc_uri_parse(target, 0));
grpc_uri_destroy(grpc_uri_parse(*canonical_target, 0));
grpc_uri_destroy(grpc_uri_parse(exec_ctx, target, 0));
grpc_uri_destroy(grpc_uri_parse(exec_ctx, *canonical_target, 0));
gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", target,
*canonical_target);
}
@ -138,7 +139,7 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
grpc_uri *uri = NULL;
char *canonical_target = NULL;
grpc_resolver_factory *factory =
resolve_factory(target, &uri, &canonical_target);
resolve_factory(exec_ctx, target, &uri, &canonical_target);
grpc_resolver *resolver;
grpc_resolver_args resolver_args;
memset(&resolver_args, 0, sizeof(resolver_args));
@ -153,21 +154,22 @@ grpc_resolver *grpc_resolver_create(grpc_exec_ctx *exec_ctx, const char *target,
return resolver;
}
char *grpc_get_default_authority(const char *target) {
char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target) {
grpc_uri *uri = NULL;
char *canonical_target = NULL;
grpc_resolver_factory *factory =
resolve_factory(target, &uri, &canonical_target);
resolve_factory(exec_ctx, target, &uri, &canonical_target);
char *authority = grpc_resolver_factory_get_default_authority(factory, uri);
grpc_uri_destroy(uri);
gpr_free(canonical_target);
return authority;
}
char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target) {
char *grpc_resolver_factory_add_default_prefix_if_needed(
grpc_exec_ctx *exec_ctx, const char *target) {
grpc_uri *uri = NULL;
char *canonical_target = NULL;
resolve_factory(target, &uri, &canonical_target);
resolve_factory(exec_ctx, target, &uri, &canonical_target);
grpc_uri_destroy(uri);
return canonical_target == NULL ? gpr_strdup(target) : canonical_target;
}

@ -74,10 +74,11 @@ grpc_resolver_factory *grpc_resolver_factory_lookup(const char *name);
/** Given a target, return a (freshly allocated with gpr_malloc) string
representing the default authority to pass from a client. */
char *grpc_get_default_authority(const char *target);
char *grpc_get_default_authority(grpc_exec_ctx *exec_ctx, const char *target);
/** Returns a newly allocated string containing \a target, adding the
default prefix if needed. */
char *grpc_resolver_factory_add_default_prefix_if_needed(const char *target);
char *grpc_resolver_factory_add_default_prefix_if_needed(
grpc_exec_ctx *exec_ctx, const char *target);
#endif /* GRPC_CORE_EXT_CLIENT_CHANNEL_RESOLVER_REGISTRY_H */

@ -331,7 +331,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
}
c->pollset_set = grpc_pollset_set_create();
grpc_resolved_address *addr = gpr_malloc(sizeof(*addr));
grpc_get_subchannel_address_arg(args->args, addr);
grpc_get_subchannel_address_arg(exec_ctx, args->args, addr);
grpc_set_initial_connect_string(&addr, &c->initial_connect_string);
grpc_resolved_address *new_address = NULL;
grpc_channel_args *new_args = NULL;
@ -787,9 +787,9 @@ grpc_call_stack *grpc_subchannel_call_get_call_stack(
return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
}
static void grpc_uri_to_sockaddr(const char *uri_str,
static void grpc_uri_to_sockaddr(grpc_exec_ctx *exec_ctx, const char *uri_str,
grpc_resolved_address *addr) {
grpc_uri *uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
grpc_uri *uri = grpc_uri_parse(exec_ctx, uri_str, 0 /* suppress_errors */);
GPR_ASSERT(uri != NULL);
if (strcmp(uri->scheme, "ipv4") == 0) {
GPR_ASSERT(parse_ipv4(uri, addr));
@ -801,12 +801,13 @@ static void grpc_uri_to_sockaddr(const char *uri_str,
grpc_uri_destroy(uri);
}
void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
const grpc_channel_args *args,
grpc_resolved_address *addr) {
const char *addr_uri_str = grpc_get_subchannel_address_uri_arg(args);
memset(addr, 0, sizeof(*addr));
if (*addr_uri_str != '\0') {
grpc_uri_to_sockaddr(addr_uri_str, addr);
grpc_uri_to_sockaddr(exec_ctx, addr_uri_str, addr);
}
}

@ -175,7 +175,8 @@ grpc_subchannel *grpc_subchannel_create(grpc_exec_ctx *exec_ctx,
const grpc_subchannel_args *args);
/// Sets \a addr from \a args.
void grpc_get_subchannel_address_arg(const grpc_channel_args *args,
void grpc_get_subchannel_address_arg(grpc_exec_ctx *exec_ctx,
const grpc_channel_args *args,
grpc_resolved_address *addr);
/// Returns the URI string for the address to connect to.

@ -35,13 +35,15 @@
#include <string.h>
#include <grpc/slice.h>
#include <grpc/slice_buffer.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/slice/percent_encoding.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
/** a size_t default value... maps to all 1's */
@ -68,11 +70,16 @@ static grpc_uri *bad_uri(const char *uri_text, size_t pos, const char *section,
return NULL;
}
/** Returns a copy of \a src[begin, end) */
static char *copy_component(const char *src, size_t begin, size_t end) {
char *out = gpr_malloc(end - begin + 1);
memcpy(out, src + begin, end - begin);
out[end - begin] = 0;
/** Returns a copy of percent decoded \a src[begin, end) */
static char *decode_and_copy_component(grpc_exec_ctx *exec_ctx, const char *src,
size_t begin, size_t end) {
grpc_slice component =
grpc_slice_from_copied_buffer(src + begin, end - begin);
grpc_slice decoded_component =
grpc_permissive_percent_decode_slice(component);
char *out = grpc_dump_slice(decoded_component, GPR_DUMP_ASCII);
grpc_slice_unref_internal(exec_ctx, component);
grpc_slice_unref_internal(exec_ctx, decoded_component);
return out;
}
@ -175,7 +182,8 @@ static void parse_query_parts(grpc_uri *uri) {
}
}
grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
int suppress_errors) {
grpc_uri *uri;
size_t scheme_begin = 0;
size_t scheme_end = NOT_SET;
@ -263,11 +271,16 @@ grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) {
}
uri = gpr_zalloc(sizeof(*uri));
uri->scheme = copy_component(uri_text, scheme_begin, scheme_end);
uri->authority = copy_component(uri_text, authority_begin, authority_end);
uri->path = copy_component(uri_text, path_begin, path_end);
uri->query = copy_component(uri_text, query_begin, query_end);
uri->fragment = copy_component(uri_text, fragment_begin, fragment_end);
uri->scheme =
decode_and_copy_component(exec_ctx, uri_text, scheme_begin, scheme_end);
uri->authority = decode_and_copy_component(exec_ctx, uri_text,
authority_begin, authority_end);
uri->path =
decode_and_copy_component(exec_ctx, uri_text, path_begin, path_end);
uri->query =
decode_and_copy_component(exec_ctx, uri_text, query_begin, query_end);
uri->fragment = decode_and_copy_component(exec_ctx, uri_text, fragment_begin,
fragment_end);
parse_query_parts(uri);
return uri;

@ -35,6 +35,7 @@
#define GRPC_CORE_EXT_CLIENT_CHANNEL_URI_PARSER_H
#include <stddef.h>
#include "src/core/lib/iomgr/exec_ctx.h"
typedef struct {
char *scheme;
@ -51,7 +52,8 @@ typedef struct {
} grpc_uri;
/** parse a uri, return NULL on failure */
grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors);
grpc_uri *grpc_uri_parse(grpc_exec_ctx *exec_ctx, const char *uri_text,
int suppress_errors);
/** return the part of a query string after the '=' in "?key=xxx&...", or NULL
* if key is not present */

@ -861,7 +861,7 @@ static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
arg = grpc_channel_args_find(args->args, GRPC_ARG_SERVER_URI);
GPR_ASSERT(arg != NULL);
GPR_ASSERT(arg->type == GRPC_ARG_STRING);
grpc_uri *uri = grpc_uri_parse(arg->value.string, true);
grpc_uri *uri = grpc_uri_parse(exec_ctx, arg->value.string, true);
GPR_ASSERT(uri->path[0] != '\0');
glb_policy->server_name =
gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);

@ -226,7 +226,7 @@ static void chttp2_connector_connect(grpc_exec_ctx *exec_ctx,
grpc_closure *notify) {
chttp2_connector *c = (chttp2_connector *)con;
grpc_resolved_address addr;
grpc_get_subchannel_address_arg(args->channel_args, &addr);
grpc_get_subchannel_address_arg(exec_ctx, args->channel_args, &addr);
gpr_mu_lock(&c->mu);
GPR_ASSERT(c->notify == NULL);
c->notify = notify;

@ -72,7 +72,8 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
arg.value.string =
grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target);
const char *to_remove[] = {GRPC_ARG_SERVER_URI};
grpc_channel_args *new_args =
grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);

@ -83,7 +83,7 @@ static grpc_subchannel_args *get_secure_naming_subchannel_args(
const char *server_uri_str = server_uri_arg->value.string;
GPR_ASSERT(server_uri_str != NULL);
grpc_uri *server_uri =
grpc_uri_parse(server_uri_str, true /* supress errors */);
grpc_uri_parse(exec_ctx, server_uri_str, true /* supress errors */);
GPR_ASSERT(server_uri != NULL);
const char *server_uri_path;
server_uri_path =
@ -96,7 +96,7 @@ static grpc_subchannel_args *get_secure_naming_subchannel_args(
const char *target_uri_str =
grpc_get_subchannel_address_uri_arg(args->args);
grpc_uri *target_uri =
grpc_uri_parse(target_uri_str, false /* suppress errors */);
grpc_uri_parse(exec_ctx, target_uri_str, false /* suppress errors */);
GPR_ASSERT(target_uri != NULL);
if (target_uri->path[0] != '\0') { // "path" may be empty
const grpc_slice key = grpc_slice_from_static_string(
@ -181,7 +181,8 @@ static grpc_channel *client_channel_factory_create_channel(
grpc_arg arg;
arg.type = GRPC_ARG_STRING;
arg.key = GRPC_ARG_SERVER_URI;
arg.value.string = grpc_resolver_factory_add_default_prefix_if_needed(target);
arg.value.string =
grpc_resolver_factory_add_default_prefix_if_needed(exec_ctx, target);
const char *to_remove[] = {GRPC_ARG_SERVER_URI};
grpc_channel_args *new_args =
grpc_channel_args_copy_and_add_and_remove(args, to_remove, 1, &arg, 1);

@ -284,9 +284,9 @@ static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte,
case GRPC_HTTP_HEADERS:
if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) {
if (grpc_http1_trace)
gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded",
gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded",
GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
return GRPC_ERROR_NONE;
return GRPC_ERROR_CREATE("HTTP header max line length exceeded");
}
parser->cur_line[parser->cur_line_length] = byte;
parser->cur_line_length++;

@ -162,6 +162,7 @@ int grpc_sockaddr_to_string(char **out,
char ntop_buf[INET6_ADDRSTRLEN];
const void *ip = NULL;
int port;
uint32_t sin6_scope_id = 0;
int ret;
*out = NULL;
@ -177,10 +178,19 @@ int grpc_sockaddr_to_string(char **out,
const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *)addr;
ip = &addr6->sin6_addr;
port = ntohs(addr6->sin6_port);
sin6_scope_id = addr6->sin6_scope_id;
}
if (ip != NULL &&
grpc_inet_ntop(addr->sa_family, ip, ntop_buf, sizeof(ntop_buf)) != NULL) {
ret = gpr_join_host_port(out, ntop_buf, port);
if (sin6_scope_id != 0) {
char *host_with_scope;
/* Enclose sin6_scope_id with the format defined in RFC 6784 section 2. */
gpr_asprintf(&host_with_scope, "%s%%25%" PRIu32, ntop_buf, sin6_scope_id);
ret = gpr_join_host_port(out, host_with_scope, port);
gpr_free(host_with_scope);
} else {
ret = gpr_join_host_port(out, ntop_buf, port);
}
} else {
ret = gpr_asprintf(out, "(sockaddr family=%d)", addr->sa_family);
}

@ -37,6 +37,8 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <assert.h>
/* Number of mutexes to allocate for events, to avoid lock contention.
Should be a prime. */
enum { event_sync_partitions = 31 };
@ -99,8 +101,12 @@ void gpr_ref_init(gpr_refcount *r, int n) { gpr_atm_rel_store(&r->count, n); }
void gpr_ref(gpr_refcount *r) { gpr_atm_no_barrier_fetch_add(&r->count, 1); }
void gpr_ref_non_zero(gpr_refcount *r) {
#ifndef NDEBUG
gpr_atm prior = gpr_atm_no_barrier_fetch_add(&r->count, 1);
GPR_ASSERT(prior > 0);
assert(prior > 0);
#else
gpr_ref(r);
#endif
}
void gpr_refn(gpr_refcount *r, int n) {

@ -161,6 +161,7 @@ struct grpc_call {
bool receiving_message;
bool requested_final_op;
bool received_final_op;
bool sent_any_op;
/* have we received initial metadata */
bool has_initial_md_been_received;
@ -488,7 +489,7 @@ void grpc_call_destroy(grpc_call *c) {
gpr_mu_lock(&c->mu);
GPR_ASSERT(!c->destroy_called);
c->destroy_called = 1;
cancel = !c->received_final_op;
cancel = c->sent_any_op && !c->received_final_op;
gpr_mu_unlock(&c->mu);
if (cancel) {
cancel_with_error(&exec_ctx, c, STATUS_FROM_API_OVERRIDE,
@ -1678,6 +1679,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx,
grpc_closure_init(&bctl->finish_batch, finish_batch, bctl,
grpc_schedule_on_exec_ctx);
stream_op->on_complete = &bctl->finish_batch;
call->sent_any_op = true;
gpr_mu_unlock(&call->mu);
execute_op(exec_ctx, call, stream_op);

@ -84,6 +84,39 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx,
}
}
#define STREAM_REF_FROM_SLICE_REF(p) \
((grpc_stream_refcount *)(((uint8_t *)p) - \
offsetof(grpc_stream_refcount, slice_refcount)))
static void slice_stream_ref(void *p) {
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p), "slice");
#else
grpc_stream_ref(STREAM_REF_FROM_SLICE_REF(p));
#endif
}
static void slice_stream_unref(grpc_exec_ctx *exec_ctx, void *p) {
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p), "slice");
#else
grpc_stream_unref(exec_ctx, STREAM_REF_FROM_SLICE_REF(p));
#endif
}
grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount,
void *buffer, size_t length) {
slice_stream_ref(&refcount->slice_refcount);
return (grpc_slice){.refcount = &refcount->slice_refcount,
.data.refcounted = {.bytes = buffer, .length = length}};
}
static const grpc_slice_refcount_vtable stream_ref_slice_vtable = {
.ref = slice_stream_ref,
.unref = slice_stream_unref,
.eq = grpc_slice_default_eq_impl,
.hash = grpc_slice_default_hash_impl};
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
grpc_iomgr_cb_func cb, void *cb_arg,
@ -95,6 +128,8 @@ void grpc_stream_ref_init(grpc_stream_refcount *refcount, int initial_refs,
#endif
gpr_ref_init(&refcount->refs, initial_refs);
grpc_closure_init(&refcount->destroy, cb, cb_arg, grpc_schedule_on_exec_ctx);
refcount->slice_refcount.vtable = &stream_ref_slice_vtable;
refcount->slice_refcount.sub_refcount = &refcount->slice_refcount;
}
static void move64(uint64_t *from, uint64_t *to) {

@ -64,6 +64,7 @@ typedef struct grpc_stream_refcount {
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
const char *object_type;
#endif
grpc_slice_refcount slice_refcount;
} grpc_stream_refcount;
#ifdef GRPC_STREAM_REFCOUNT_DEBUG
@ -84,6 +85,11 @@ void grpc_stream_unref(grpc_exec_ctx *exec_ctx, grpc_stream_refcount *refcount);
grpc_stream_ref_init(rc, ir, cb, cb_arg)
#endif
/* Wrap a buffer that is owned by some stream object into a slice that shares
the same refcount */
grpc_slice grpc_slice_from_stream_owned_buffer(grpc_stream_refcount *refcount,
void *buffer, size_t length);
typedef struct {
uint64_t framing_bytes;
uint64_t data_bytes;

@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses(["notice"]) # 3-clause BSD
exports_files([
"ca.pem",
"server1.key",

@ -63,7 +63,9 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check(
ServerContext* context, const ByteBuffer* request, ByteBuffer* response) {
// Decode request.
std::vector<Slice> slices;
request->Dump(&slices);
if (!request->Dump(&slices).ok()) {
return Status(StatusCode::INVALID_ARGUMENT, "");
}
uint8_t* request_bytes = nullptr;
bool request_bytes_owned = false;
size_t request_size = 0;

@ -158,7 +158,7 @@ $ composer install
### Protobuf compiler
Again if you don't have it already, you need to install the protobuf compiler
`protoc`, version 3.2.0+.
`protoc`, version 3.1.0+ (the newer the better).
If `protoc` hasn't been installed, you can download the `protoc` binaries from
[the protocol buffers Github repository](https://github.com/google/protobuf/releases).

@ -5,7 +5,7 @@
"version": "1.2.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -1004,7 +1004,7 @@ def unary_unary_rpc_method_handler(behavior,
An RpcMethodHandler for a unary-unary RPC method constructed from the given
parameters.
"""
from grpc import _utilities
from grpc import _utilities # pylint: disable=cyclic-import
return _utilities.RpcMethodHandler(False, False, request_deserializer,
response_serializer, behavior, None,
None, None)
@ -1025,7 +1025,7 @@ def unary_stream_rpc_method_handler(behavior,
An RpcMethodHandler for a unary-stream RPC method constructed from the
given parameters.
"""
from grpc import _utilities
from grpc import _utilities # pylint: disable=cyclic-import
return _utilities.RpcMethodHandler(False, True, request_deserializer,
response_serializer, None, behavior,
None, None)
@ -1046,7 +1046,7 @@ def stream_unary_rpc_method_handler(behavior,
An RpcMethodHandler for a stream-unary RPC method constructed from the
given parameters.
"""
from grpc import _utilities
from grpc import _utilities # pylint: disable=cyclic-import
return _utilities.RpcMethodHandler(True, False, request_deserializer,
response_serializer, None, None,
behavior, None)
@ -1068,7 +1068,7 @@ def stream_stream_rpc_method_handler(behavior,
An RpcMethodHandler for a stream-stream RPC method constructed from the
given parameters.
"""
from grpc import _utilities
from grpc import _utilities # pylint: disable=cyclic-import
return _utilities.RpcMethodHandler(True, True, request_deserializer,
response_serializer, None, None, None,
behavior)
@ -1085,7 +1085,7 @@ def method_handlers_generic_handler(service, method_handlers):
Returns:
A GenericRpcHandler constructed from the given parameters.
"""
from grpc import _utilities
from grpc import _utilities # pylint: disable=cyclic-import
return _utilities.DictionaryGenericHandler(service, method_handlers)
@ -1124,7 +1124,7 @@ def metadata_call_credentials(metadata_plugin, name=None):
Returns:
A CallCredentials.
"""
from grpc import _plugin_wrapping
from grpc import _plugin_wrapping # pylint: disable=cyclic-import
if name is None:
try:
effective_name = metadata_plugin.__name__
@ -1147,7 +1147,7 @@ def access_token_call_credentials(access_token):
Returns:
A CallCredentials.
"""
from grpc import _auth
from grpc import _auth # pylint: disable=cyclic-import
return metadata_call_credentials(
_auth.AccessTokenCallCredentials(access_token))
@ -1161,7 +1161,7 @@ def composite_call_credentials(*call_credentials):
Returns:
A CallCredentials object composed of the given CallCredentials objects.
"""
from grpc import _credential_composition
from grpc import _credential_composition # pylint: disable=cyclic-import
cygrpc_call_credentials = tuple(
single_call_credentials._credentials
for single_call_credentials in call_credentials)
@ -1180,7 +1180,7 @@ def composite_channel_credentials(channel_credentials, *call_credentials):
A ChannelCredentials composed of the given ChannelCredentials and
CallCredentials objects.
"""
from grpc import _credential_composition
from grpc import _credential_composition # pylint: disable=cyclic-import
cygrpc_call_credentials = tuple(
single_call_credentials._credentials
for single_call_credentials in call_credentials)
@ -1237,7 +1237,7 @@ def channel_ready_future(channel):
A Future that matures when the given Channel has connectivity
ChannelConnectivity.READY.
"""
from grpc import _utilities
from grpc import _utilities # pylint: disable=cyclic-import
return _utilities.channel_ready_future(channel)
@ -1252,7 +1252,7 @@ def insecure_channel(target, options=None):
Returns:
A Channel to the target through which RPCs may be conducted.
"""
from grpc import _channel
from grpc import _channel # pylint: disable=cyclic-import
return _channel.Channel(target, () if options is None else options, None)
@ -1268,7 +1268,7 @@ def secure_channel(target, credentials, options=None):
Returns:
A Channel to the target through which RPCs may be conducted.
"""
from grpc import _channel
from grpc import _channel # pylint: disable=cyclic-import
return _channel.Channel(target, () if options is None else options,
credentials._credentials)
@ -1290,7 +1290,7 @@ def server(thread_pool, handlers=None, options=None):
Returns:
A Server with which RPCs can be serviced.
"""
from grpc import _server
from grpc import _server # pylint: disable=cyclic-import
return _server.Server(thread_pool, () if handlers is None else handlers, ()
if options is None else options)

@ -39,6 +39,19 @@ def _sign_request(callback, token, error):
callback(metadata, error)
def _create_get_token_callback(callback):
def get_token_callback(future):
try:
access_token = future.result().access_token
except Exception as exception: # pylint: disable=broad-except
_sign_request(callback, None, exception)
else:
_sign_request(callback, access_token, None)
return get_token_callback
class GoogleCallCredentials(grpc.AuthMetadataPlugin):
"""Metadata wrapper for GoogleCredentials from the oauth2client library."""
@ -59,16 +72,7 @@ class GoogleCallCredentials(grpc.AuthMetadataPlugin):
additional_claims={'aud': context.service_url})
else:
future = self._pool.submit(self._credentials.get_access_token)
future.add_done_callback(
lambda x: self._get_token_callback(callback, x))
def _get_token_callback(self, callback, future):
try:
access_token = future.result().access_token
except Exception as e:
_sign_request(callback, None, e)
else:
_sign_request(callback, access_token, None)
future.add_done_callback(_create_get_token_callback(callback))
def __del__(self):
self._pool.shutdown(wait=False)

@ -200,7 +200,7 @@ def _consume_request_iterator(request_iterator, state, call,
request = next(request_iterator)
except StopIteration:
break
except Exception as e:
except Exception: # pylint: disable=broad-except
logging.exception("Exception iterating requests!")
call.cancel()
_abort(state, grpc.StatusCode.UNKNOWN,
@ -387,13 +387,14 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call):
with self._state.condition:
while self._state.initial_metadata is None:
self._state.condition.wait()
return _common.application_metadata(self._state.initial_metadata)
return _common.to_application_metadata(self._state.initial_metadata)
def trailing_metadata(self):
with self._state.condition:
while self._state.trailing_metadata is None:
self._state.condition.wait()
return _common.application_metadata(self._state.trailing_metadata)
return _common.to_application_metadata(
self._state.trailing_metadata)
def code(self):
with self._state.condition:
@ -473,7 +474,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
operations = (
cygrpc.operation_send_initial_metadata(
_common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
_common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
@ -563,7 +564,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
)), event_handler)
operations = (
cygrpc.operation_send_initial_metadata(
_common.cygrpc_metadata(metadata),
_common.to_cygrpc_metadata(metadata),
_EMPTY_FLAGS), cygrpc.operation_send_message(
serialized_request, _EMPTY_FLAGS),
cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
@ -603,7 +604,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
None)
operations = (
cygrpc.operation_send_initial_metadata(
_common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
_common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
cygrpc.operation_receive_message(_EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
call_error = call.start_client_batch(
@ -657,7 +658,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
event_handler)
operations = (
cygrpc.operation_send_initial_metadata(
_common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
_common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
cygrpc.operation_receive_message(_EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
call_error = call.start_client_batch(
@ -700,7 +701,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
event_handler)
operations = (
cygrpc.operation_send_initial_metadata(
_common.cygrpc_metadata(metadata), _EMPTY_FLAGS),
_common.to_cygrpc_metadata(metadata), _EMPTY_FLAGS),
cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),)
call_error = call.start_client_batch(
cygrpc.Operations(operations), event_handler)

@ -97,22 +97,22 @@ def decode(b):
def channel_args(options):
channel_args = []
cygrpc_args = []
for key, value in options:
if isinstance(value, six.string_types):
channel_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
cygrpc_args.append(cygrpc.ChannelArg(encode(key), encode(value)))
else:
channel_args.append(cygrpc.ChannelArg(encode(key), value))
return cygrpc.ChannelArgs(channel_args)
cygrpc_args.append(cygrpc.ChannelArg(encode(key), value))
return cygrpc.ChannelArgs(cygrpc_args)
def cygrpc_metadata(application_metadata):
def to_cygrpc_metadata(application_metadata):
return EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
cygrpc.Metadatum(encode(key), encode(value))
for key, value in application_metadata)
def application_metadata(cygrpc_metadata):
def to_application_metadata(cygrpc_metadata):
if cygrpc_metadata is None:
return ()
else:

@ -66,9 +66,9 @@ class _WrappedCygrpcCallback(object):
def _invoke_success(self, metadata):
try:
cygrpc_metadata = _common.cygrpc_metadata(metadata)
except Exception as error:
self._invoke_failure(error)
cygrpc_metadata = _common.to_cygrpc_metadata(metadata)
except Exception as exception: # pylint: disable=broad-except
self._invoke_failure(exception)
return
self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, b'')

@ -142,14 +142,14 @@ def _abort(state, call, code, details):
effective_details = details if state.details is None else state.details
if state.initial_metadata_allowed:
operations = (cygrpc.operation_send_initial_metadata(
_common.EMPTY_METADATA, _EMPTY_FLAGS),
cygrpc.operation_send_status_from_server(
_common.cygrpc_metadata(state.trailing_metadata),
effective_code, effective_details, _EMPTY_FLAGS),)
_common.EMPTY_METADATA,
_EMPTY_FLAGS), cygrpc.operation_send_status_from_server(
_common.to_cygrpc_metadata(state.trailing_metadata),
effective_code, effective_details, _EMPTY_FLAGS),)
token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
else:
operations = (cygrpc.operation_send_status_from_server(
_common.cygrpc_metadata(state.trailing_metadata),
_common.to_cygrpc_metadata(state.trailing_metadata),
effective_code, effective_details, _EMPTY_FLAGS),)
token = _SEND_STATUS_FROM_SERVER_TOKEN
call.start_server_batch(
@ -250,7 +250,7 @@ class _Context(grpc.ServicerContext):
self._state.disable_next_compression = True
def invocation_metadata(self):
return _common.application_metadata(self._rpc_event.request_metadata)
return _common.to_application_metadata(self._rpc_event.request_metadata)
def peer(self):
return _common.decode(self._rpc_event.operation_call.peer())
@ -262,7 +262,8 @@ class _Context(grpc.ServicerContext):
else:
if self._state.initial_metadata_allowed:
operation = cygrpc.operation_send_initial_metadata(
_common.cygrpc_metadata(initial_metadata), _EMPTY_FLAGS)
_common.to_cygrpc_metadata(initial_metadata),
_EMPTY_FLAGS)
self._rpc_event.operation_call.start_server_batch(
cygrpc.Operations((operation,)),
_send_initial_metadata(self._state))
@ -273,7 +274,7 @@ class _Context(grpc.ServicerContext):
def set_trailing_metadata(self, trailing_metadata):
with self._state.condition:
self._state.trailing_metadata = _common.cygrpc_metadata(
self._state.trailing_metadata = _common.to_cygrpc_metadata(
trailing_metadata)
def set_code(self, code):
@ -342,7 +343,7 @@ def _unary_request(rpc_event, state, request_deserializer):
if state.client is _CANCELLED or state.statused:
return None
else:
start_server_batch_result = rpc_event.operation_call.start_server_batch(
rpc_event.operation_call.start_server_batch(
cygrpc.Operations(
(cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
_receive_message(state, rpc_event.operation_call,
@ -436,7 +437,8 @@ def _send_response(rpc_event, state, serialized_response):
def _status(rpc_event, state, serialized_response):
with state.condition:
if state.client is not _CANCELLED:
trailing_metadata = _common.cygrpc_metadata(state.trailing_metadata)
trailing_metadata = _common.to_cygrpc_metadata(
state.trailing_metadata)
code = _completion_code(state)
details = _details(state)
operations = [

@ -30,7 +30,6 @@
import grpc
from grpc import _common
from grpc._cython import cygrpc
from grpc.beta import interfaces
from grpc.framework.common import cardinality
from grpc.framework.foundation import future
@ -621,8 +620,8 @@ class _GenericStub(face.GenericStub):
class _DynamicStub(face.DynamicStub):
def __init__(self, generic_stub, group, cardinalities):
self._generic_stub = generic_stub
def __init__(self, backing_generic_stub, group, cardinalities):
self._generic_stub = backing_generic_stub
self._group = group
self._cardinalities = cardinalities

@ -1,159 +0,0 @@
# Copyright 2015, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Affords a connectivity-state-listenable channel."""
import threading
import time
from grpc._adapter import _low
from grpc._adapter import _types
from grpc.beta import interfaces
from grpc.framework.foundation import callable_util
_CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
'Exception calling channel subscription callback!')
_LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
state: connectivity
for state, connectivity in zip(_types.ConnectivityState,
interfaces.ChannelConnectivity)
}
class ConnectivityChannel(object):
def __init__(self, low_channel):
self._lock = threading.Lock()
self._low_channel = low_channel
self._polling = False
self._connectivity = None
self._try_to_connect = False
self._callbacks_and_connectivities = []
self._delivering = False
def _deliveries(self, connectivity):
callbacks_needing_update = []
for callback_and_connectivity in self._callbacks_and_connectivities:
callback, callback_connectivity = callback_and_connectivity
if callback_connectivity is not connectivity:
callbacks_needing_update.append(callback)
callback_and_connectivity[1] = connectivity
return callbacks_needing_update
def _deliver(self, initial_connectivity, initial_callbacks):
connectivity = initial_connectivity
callbacks = initial_callbacks
while True:
for callback in callbacks:
callable_util.call_logging_exceptions(
callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
connectivity)
with self._lock:
callbacks = self._deliveries(self._connectivity)
if callbacks:
connectivity = self._connectivity
else:
self._delivering = False
return
def _spawn_delivery(self, connectivity, callbacks):
delivering_thread = threading.Thread(
target=self._deliver, args=(connectivity, callbacks,))
delivering_thread.start()
self._delivering = True
# TODO(issue 3064): Don't poll.
def _poll_connectivity(self, low_channel, initial_try_to_connect):
try_to_connect = initial_try_to_connect
low_connectivity = low_channel.check_connectivity_state(try_to_connect)
with self._lock:
self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
low_connectivity]
callbacks = tuple(
callback
for callback, unused_but_known_to_be_none_connectivity in
self._callbacks_and_connectivities)
for callback_and_connectivity in self._callbacks_and_connectivities:
callback_and_connectivity[1] = self._connectivity
if callbacks:
self._spawn_delivery(self._connectivity, callbacks)
completion_queue = _low.CompletionQueue()
while True:
low_channel.watch_connectivity_state(low_connectivity,
time.time() + 0.2,
completion_queue, None)
event = completion_queue.next()
with self._lock:
if not self._callbacks_and_connectivities and not self._try_to_connect:
self._polling = False
self._connectivity = None
completion_queue.shutdown()
break
try_to_connect = self._try_to_connect
self._try_to_connect = False
if event.success or try_to_connect:
low_connectivity = low_channel.check_connectivity_state(
try_to_connect)
with self._lock:
self._connectivity = _LOW_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
low_connectivity]
if not self._delivering:
callbacks = self._deliveries(self._connectivity)
if callbacks:
self._spawn_delivery(self._connectivity, callbacks)
def subscribe(self, callback, try_to_connect):
with self._lock:
if not self._callbacks_and_connectivities and not self._polling:
polling_thread = threading.Thread(
target=self._poll_connectivity,
args=(self._low_channel, bool(try_to_connect)))
polling_thread.start()
self._polling = True
self._callbacks_and_connectivities.append([callback, None])
elif not self._delivering and self._connectivity is not None:
self._spawn_delivery(self._connectivity, (callback,))
self._try_to_connect |= bool(try_to_connect)
self._callbacks_and_connectivities.append(
[callback, self._connectivity])
else:
self._try_to_connect |= bool(try_to_connect)
self._callbacks_and_connectivities.append([callback, None])
def unsubscribe(self, callback):
with self._lock:
for index, (subscribed_callback, unused_connectivity
) in enumerate(self._callbacks_and_connectivities):
if callback == subscribed_callback:
self._callbacks_and_connectivities.pop(index)
break
def low_channel(self):
return self._low_channel

@ -78,7 +78,7 @@ class _FaceServicerContext(face.ServicerContext):
return _ServerProtocolContext(self._servicer_context)
def invocation_metadata(self):
return _common.cygrpc_metadata(
return _common.to_cygrpc_metadata(
self._servicer_context.invocation_metadata())
def initial_metadata(self, initial_metadata):
@ -351,27 +351,27 @@ class _GenericRpcHandler(grpc.GenericRpcHandler):
class _Server(interfaces.Server):
def __init__(self, server):
self._server = server
def __init__(self, grpc_server):
self._grpc_server = grpc_server
def add_insecure_port(self, address):
return self._server.add_insecure_port(address)
return self._grpc_server.add_insecure_port(address)
def add_secure_port(self, address, server_credentials):
return self._server.add_secure_port(address, server_credentials)
return self._grpc_server.add_secure_port(address, server_credentials)
def start(self):
self._server.start()
self._grpc_server.start()
def stop(self, grace):
return self._server.stop(grace)
return self._grpc_server.stop(grace)
def __enter__(self):
self._server.start()
self._grpc_server.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self._server.stop(None)
self._grpc_server.stop(None)
return False

@ -29,16 +29,15 @@
"""Entry points into the Beta API of gRPC Python."""
# threading is referenced from specification in this module.
import abc
import enum
import threading # pylint: disable=unused-import
# cardinality and face are referenced from specification in this module.
# interfaces, cardinality, and face are referenced from specification in this
# module.
import grpc
from grpc import _auth
from grpc.beta import _client_adaptations
from grpc.beta import _server_adaptations
from grpc.beta import interfaces
from grpc.beta import interfaces # pylint: disable=unused-import
from grpc.framework.common import cardinality # pylint: disable=unused-import
from grpc.framework.interfaces.face import face # pylint: disable=unused-import
@ -218,7 +217,7 @@ def dynamic_stub(channel, service, cardinalities, options=None):
Returns:
A face.DynamicStub with which RPCs can be invoked.
"""
effective_options = StubOptions() if options is None else options
effective_options = _EMPTY_STUB_OPTIONS if options is None else options
return _client_adaptations.dynamic_stub(
channel._channel, # pylint: disable=protected-access
service,

@ -39,7 +39,7 @@ def _wrap(behavior):
def _wrapping(*args, **kwargs):
try:
return behavior(*args, **kwargs)
except Exception as e:
except Exception:
logging.exception(
'Unexpected exception from %s executed in logging pool!',
behavior)

@ -31,6 +31,7 @@
import argparse
import grpc
import time
from src.proto.grpc.testing import test_pb2
from src.proto.grpc.testing import messages_pb2
@ -75,6 +76,7 @@ def _goaway(stub):
first_response = stub.UnaryCall(_SIMPLE_REQUEST)
_validate_payload_type_and_length(first_response, messages_pb2.COMPRESSABLE,
_RESPONSE_SIZE)
time.sleep(1)
second_response = stub.UnaryCall(_SIMPLE_REQUEST)
_validate_payload_type_and_length(second_response,
messages_pb2.COMPRESSABLE, _RESPONSE_SIZE)

@ -9,7 +9,7 @@
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -191,7 +191,7 @@
'test/core/util/debugger_macros.c',
'test/core/util/test_config.{c,h}',
'test/core/util/port.h',
'test/core/util/port_posix.c',
'test/core/util/port.c',
'test/core/util/port_server_client.{c,h}'
end
end

@ -12,7 +12,7 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
<date>2017-01-13</date>
<date>2017-03-01</date>
<time>16:06:07</time>
<version>
<release>${settings.php_version.php()}</release>
@ -24,8 +24,8 @@
</stability>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@ -312,8 +312,8 @@
</release>
<release>
<version>
<release>1.1.0dev</release>
<api>1.1.0dev</api>
<release>1.1.0RC1</release>
<api>1.1.0RC1</api>
</version>
<stability>
<release>beta</release>
@ -323,7 +323,39 @@
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2017-01-31</date>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.2.0RC1</release>
<api>1.2.0RC1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2017-03-01</date>
<license>BSD</license>
<notes>
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
</release>
</changelog>

@ -7,7 +7,7 @@
"version": "${settings.php_version.php_composer()}",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses(["notice"]) # 3-clause BSD
cc_test(
name = "context_test",
srcs = ["context_test.c"],

@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses(["notice"]) # 3-clause BSD
cc_test(
name = "channel_args_test",
srcs = ["channel_args_test.c"],

@ -0,0 +1,116 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/ext/client_channel/parse_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include <string.h>
#ifdef GRPC_HAVE_UNIX_SOCKET
#include <sys/un.h>
#endif
#include <grpc/support/log.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/socket_utils.h"
#include "test/core/util/test_config.h"
#ifdef GRPC_HAVE_UNIX_SOCKET
static void test_parse_unix(const char *uri_text, const char *pathname) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
grpc_resolved_address addr;
GPR_ASSERT(1 == parse_unix(uri, &addr));
struct sockaddr_un *addr_un = (struct sockaddr_un *)addr.addr;
GPR_ASSERT(AF_UNIX == addr_un->sun_family);
GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname));
grpc_uri_destroy(uri);
grpc_exec_ctx_finish(&exec_ctx);
}
#else /* GRPC_HAVE_UNIX_SOCKET */
static void test_parse_unix(const char *uri_text, const char *pathname) {}
#endif /* GRPC_HAVE_UNIX_SOCKET */
static void test_parse_ipv4(const char *uri_text, const char *host,
unsigned short port) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
grpc_resolved_address addr;
char ntop_buf[INET_ADDRSTRLEN];
GPR_ASSERT(1 == parse_ipv4(uri, &addr));
struct sockaddr_in *addr_in = (struct sockaddr_in *)addr.addr;
GPR_ASSERT(AF_INET == addr_in->sin_family);
GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET, &addr_in->sin_addr, ntop_buf,
sizeof(ntop_buf)));
GPR_ASSERT(0 == strcmp(ntop_buf, host));
GPR_ASSERT(ntohs(addr_in->sin_port) == port);
grpc_uri_destroy(uri);
grpc_exec_ctx_finish(&exec_ctx);
}
static void test_parse_ipv6(const char *uri_text, const char *host,
unsigned short port, uint32_t scope_id) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
grpc_resolved_address addr;
char ntop_buf[INET6_ADDRSTRLEN];
GPR_ASSERT(1 == parse_ipv6(uri, &addr));
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr.addr;
GPR_ASSERT(AF_INET6 == addr_in6->sin6_family);
GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET6, &addr_in6->sin6_addr, ntop_buf,
sizeof(ntop_buf)));
GPR_ASSERT(0 == strcmp(ntop_buf, host));
GPR_ASSERT(ntohs(addr_in6->sin6_port) == port);
GPR_ASSERT(addr_in6->sin6_scope_id == scope_id);
grpc_uri_destroy(uri);
grpc_exec_ctx_finish(&exec_ctx);
}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_parse_unix("unix:/path/name", "/path/name");
test_parse_ipv4("ipv4:192.0.2.1:12345", "192.0.2.1", 12345);
test_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0);
test_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2);
}

@ -69,7 +69,7 @@ static grpc_error *my_resolve_address(const char *name, const char *addr,
static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx,
const char *name) {
grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns");
grpc_uri *uri = grpc_uri_parse(name, 0);
grpc_uri *uri = grpc_uri_parse(exec_ctx, name, 0);
GPR_ASSERT(uri);
grpc_resolver_args args;
memset(&args, 0, sizeof(args));

@ -43,7 +43,7 @@ static grpc_combiner *g_combiner;
static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(string, 0);
grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
grpc_resolver_args args;
grpc_resolver *resolver;
gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
@ -61,7 +61,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
static void test_fails(grpc_resolver_factory *factory, const char *string) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(string, 0);
grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
grpc_resolver_args args;
grpc_resolver *resolver;
gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,

@ -57,7 +57,7 @@ void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(string, 0);
grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
grpc_resolver_args args;
grpc_resolver *resolver;
gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string,
@ -84,7 +84,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
static void test_fails(grpc_resolver_factory *factory, const char *string) {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(string, 0);
grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0);
grpc_resolver_args args;
grpc_resolver *resolver;
gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string,

@ -38,6 +38,7 @@
#include <grpc/support/alloc.h>
#include "src/core/ext/client_channel/uri_parser.h"
#include "src/core/lib/iomgr/exec_ctx.h"
bool squelch = true;
bool leak_check = true;
@ -47,10 +48,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
memcpy(s, data, size);
s[size] = 0;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *x;
if ((x = grpc_uri_parse(s, 1))) {
if ((x = grpc_uri_parse(&exec_ctx, s, 1))) {
grpc_uri_destroy(x);
}
grpc_exec_ctx_finish(&exec_ctx);
gpr_free(s);
return 0;
}

@ -37,29 +37,35 @@
#include <grpc/support/log.h>
#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/util/test_config.h"
static void test_succeeds(const char *uri_text, const char *scheme,
const char *authority, const char *path,
const char *query, const char *fragment) {
grpc_uri *uri = grpc_uri_parse(uri_text, 0);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
GPR_ASSERT(uri);
GPR_ASSERT(0 == strcmp(scheme, uri->scheme));
GPR_ASSERT(0 == strcmp(authority, uri->authority));
GPR_ASSERT(0 == strcmp(path, uri->path));
GPR_ASSERT(0 == strcmp(query, uri->query));
GPR_ASSERT(0 == strcmp(fragment, uri->fragment));
grpc_exec_ctx_finish(&exec_ctx);
grpc_uri_destroy(uri);
}
static void test_fails(const char *uri_text) {
GPR_ASSERT(NULL == grpc_uri_parse(uri_text, 0));
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
GPR_ASSERT(NULL == grpc_uri_parse(&exec_ctx, uri_text, 0));
grpc_exec_ctx_finish(&exec_ctx);
}
static void test_query_parts() {
{
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
const char *uri_text = "http://foo/path?a&b=B&c=&#frag";
grpc_uri *uri = grpc_uri_parse(uri_text, 0);
grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
GPR_ASSERT(uri);
GPR_ASSERT(0 == strcmp("http", uri->scheme));
@ -86,12 +92,14 @@ static void test_query_parts() {
GPR_ASSERT(NULL == grpc_uri_get_query_arg(uri, ""));
GPR_ASSERT(0 == strcmp("frag", uri->fragment));
grpc_exec_ctx_finish(&exec_ctx);
grpc_uri_destroy(uri);
}
{
/* test the current behavior of multiple query part values */
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
const char *uri_text = "http://auth/path?foo=bar=baz&foobar==";
grpc_uri *uri = grpc_uri_parse(uri_text, 0);
grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
GPR_ASSERT(uri);
GPR_ASSERT(0 == strcmp("http", uri->scheme));
@ -103,12 +111,14 @@ static void test_query_parts() {
GPR_ASSERT(0 == strcmp("bar", grpc_uri_get_query_arg(uri, "foo")));
GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "foobar")));
grpc_exec_ctx_finish(&exec_ctx);
grpc_uri_destroy(uri);
}
{
/* empty query */
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
const char *uri_text = "http://foo/path";
grpc_uri *uri = grpc_uri_parse(uri_text, 0);
grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0);
GPR_ASSERT(uri);
GPR_ASSERT(0 == strcmp("http", uri->scheme));
@ -119,6 +129,7 @@ static void test_query_parts() {
GPR_ASSERT(NULL == uri->query_parts);
GPR_ASSERT(NULL == uri->query_parts_values);
GPR_ASSERT(0 == strcmp("", uri->fragment));
grpc_exec_ctx_finish(&exec_ctx);
grpc_uri_destroy(uri);
}
}
@ -142,6 +153,8 @@ int main(int argc, char **argv) {
test_succeeds("http:?legit#twice", "http", "", "", "legit", "twice");
test_succeeds("http://foo?bar#lol?", "http", "foo", "", "bar", "lol?");
test_succeeds("http://foo?bar#lol?/", "http", "foo", "", "bar", "lol?/");
test_succeeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "",
"[2001:db8::1%2]:12345", "", "");
test_fails("xyz");
test_fails("http:?dangling-pct-%0");

@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses(["notice"]) # 3-clause BSD
cc_test(
name = "algorithm_test",
srcs = ["algorithm_test.c"],

@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses(["notice"]) # 3-clause BSD
cc_test(
name = "client_ssl",
srcs = ["client_ssl.c"],

@ -70,6 +70,12 @@ static grpc_resolved_address make_addr6(const uint8_t *data, size_t data_len) {
return resolved_addr6;
}
static void set_addr6_scope_id(grpc_resolved_address *addr, uint32_t scope_id) {
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr->addr;
GPR_ASSERT(addr6->sin6_family == AF_INET6);
addr6->sin6_scope_id = scope_id;
}
static const uint8_t kMapped[] = {0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0xff, 0xff, 192, 0, 2, 1};
@ -222,6 +228,16 @@ static void test_sockaddr_to_string(void) {
expect_sockaddr_str("[2001:db8::1]:12345", &input6, 1);
expect_sockaddr_uri("ipv6:[2001:db8::1]:12345", &input6);
set_addr6_scope_id(&input6, 2);
expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 0);
expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 1);
expect_sockaddr_uri("ipv6:[2001:db8::1%252]:12345", &input6);
set_addr6_scope_id(&input6, 101);
expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 0);
expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 1);
expect_sockaddr_uri("ipv6:[2001:db8::1%25101]:12345", &input6);
input6 = make_addr6(kMapped, sizeof(kMapped));
expect_sockaddr_str("[::ffff:192.0.2.1]:12345", &input6, 0);
expect_sockaddr_str("192.0.2.1:12345", &input6, 1);

@ -454,7 +454,8 @@ int main(int argc, char **argv) {
const grpc_channel_args channel_args = {1, chan_args};
struct ifaddrs *ifa = NULL;
struct ifaddrs *ifa_it;
test_addrs dst_addrs;
// Zalloc dst_addrs to avoid oversized frames.
test_addrs *dst_addrs = gpr_zalloc(sizeof(*dst_addrs));
grpc_test_init(argc, argv);
grpc_init();
g_pollset = gpr_zalloc(grpc_pollset_size());
@ -469,24 +470,25 @@ int main(int argc, char **argv) {
gpr_log(GPR_ERROR, "getifaddrs: %s", strerror(errno));
return EXIT_FAILURE;
}
dst_addrs.naddrs = 0;
for (ifa_it = ifa; ifa_it != NULL && dst_addrs.naddrs < MAX_ADDRS;
dst_addrs->naddrs = 0;
for (ifa_it = ifa; ifa_it != NULL && dst_addrs->naddrs < MAX_ADDRS;
ifa_it = ifa_it->ifa_next) {
if (ifa_it->ifa_addr == NULL) {
continue;
} else if (ifa_it->ifa_addr->sa_family == AF_INET) {
dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in);
dst_addrs->addrs[dst_addrs->naddrs].addr.len = sizeof(struct sockaddr_in);
} else if (ifa_it->ifa_addr->sa_family == AF_INET6) {
dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in6);
dst_addrs->addrs[dst_addrs->naddrs].addr.len =
sizeof(struct sockaddr_in6);
} else {
continue;
}
memcpy(dst_addrs.addrs[dst_addrs.naddrs].addr.addr, ifa_it->ifa_addr,
dst_addrs.addrs[dst_addrs.naddrs].addr.len);
memcpy(dst_addrs->addrs[dst_addrs->naddrs].addr.addr, ifa_it->ifa_addr,
dst_addrs->addrs[dst_addrs->naddrs].addr.len);
GPR_ASSERT(
grpc_sockaddr_set_port(&dst_addrs.addrs[dst_addrs.naddrs].addr, 0));
test_addr_init_str(&dst_addrs.addrs[dst_addrs.naddrs]);
++dst_addrs.naddrs;
grpc_sockaddr_set_port(&dst_addrs->addrs[dst_addrs->naddrs].addr, 0));
test_addr_init_str(&dst_addrs->addrs[dst_addrs->naddrs]);
++dst_addrs->naddrs;
}
freeifaddrs(ifa);
ifa = NULL;
@ -495,20 +497,21 @@ int main(int argc, char **argv) {
test_connect(1, NULL, NULL, false);
test_connect(10, NULL, NULL, false);
/* Set dst_addrs.addrs[i].len=0 for dst_addrs that are unreachable with a "::"
listener. */
test_connect(1, NULL, &dst_addrs, true);
/* Set dst_addrs->addrs[i].len=0 for dst_addrs that are unreachable with a
"::" listener. */
test_connect(1, NULL, dst_addrs, true);
/* Test connect(2) with dst_addrs. */
test_connect(1, &channel_args, &dst_addrs, false);
test_connect(1, &channel_args, dst_addrs, false);
/* Test connect(2) with dst_addrs. */
test_connect(10, &channel_args, &dst_addrs, false);
test_connect(10, &channel_args, dst_addrs, false);
grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
grpc_schedule_on_exec_ctx);
grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
grpc_exec_ctx_finish(&exec_ctx);
grpc_shutdown();
gpr_free(dst_addrs);
gpr_free(g_pollset);
return EXIT_SUCCESS;
}

@ -146,6 +146,7 @@ int main(int argc, char **argv) {
TEST_VECTOR("\x0f", "%0F", grpc_url_percent_encoding_unreserved_bytes);
TEST_VECTOR("\xff", "%FF", grpc_url_percent_encoding_unreserved_bytes);
TEST_VECTOR("\xee", "%EE", grpc_url_percent_encoding_unreserved_bytes);
TEST_VECTOR("%2", "%252", grpc_url_percent_encoding_unreserved_bytes);
TEST_NONCONFORMANT_VECTOR("%", "%",
grpc_url_percent_encoding_unreserved_bytes);
TEST_NONCONFORMANT_VECTOR("%A", "%A",

@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses(["notice"]) # 3-clause BSD
cc_test(
name = "alloc_test",
srcs = ["alloc_test.c"],

@ -27,6 +27,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses(["notice"]) # 3-clause BSD
cc_test(
name = "alarm_test",
srcs = ["alarm_test.c"],

@ -64,6 +64,13 @@ cc_test(
copts = ['-std=c99']
)
cc_test(
name = "stream_owned_slice_test",
srcs = ["stream_owned_slice_test.c"],
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
copts = ['-std=c99']
)
cc_test(
name = "timeout_encoding_test",
srcs = ["timeout_encoding_test.c"],

@ -0,0 +1,58 @@
/*
*
* Copyright 2017, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/lib/transport/transport.h"
#include "test/core/util/test_config.h"
#include <grpc/support/log.h>
static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {}
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
uint8_t buffer[] = "abc123";
grpc_stream_refcount r;
GRPC_STREAM_REF_INIT(&r, 1, do_nothing, NULL, "test");
GPR_ASSERT(r.refs.count == 1);
grpc_slice slice =
grpc_slice_from_stream_owned_buffer(&r, buffer, sizeof(buffer));
GPR_ASSERT(GRPC_SLICE_START_PTR(slice) == buffer);
GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == sizeof(buffer));
GPR_ASSERT(r.refs.count == 2);
grpc_slice_unref(slice);
GPR_ASSERT(r.refs.count == 1);
return 0;
}

@ -51,9 +51,8 @@ cc_library(
"mock_endpoint.c",
"parse_hexstring.c",
"passthru_endpoint.c",
"port_posix.c",
"port.c",
"port_server_client.c",
"port_windows.c",
"reconnect_server.c",
"slice_splitter.c",
"test_tcp_server.c",

@ -33,17 +33,24 @@
#include "src/core/lib/iomgr/port.h"
#include "test/core/util/test_config.h"
#if defined(GRPC_UV) && defined(GRPC_TEST_PICK_PORT)
#if defined(GRPC_TEST_PICK_PORT)
#include "test/core/util/port.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/support/env.h"
#include "test/core/util/port.h"
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "test/core/util/port_server_client.h"
// Almost everything in this file has been copied from port_posix.c
static int *chosen_ports = NULL;
static size_t num_chosen_ports = 0;
@ -51,7 +58,6 @@ static int free_chosen_port(int port) {
size_t i;
int found = 0;
size_t found_at = 0;
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
/* Find the port and erase it from the list, then tell the server it can be
freed. */
for (i = 0; i < num_chosen_ports; i++) {
@ -64,24 +70,16 @@ static int free_chosen_port(int port) {
if (found) {
chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1];
num_chosen_ports--;
if (env) {
grpc_free_port_using_server(env, port);
}
grpc_free_port_using_server(port);
}
gpr_free(env);
return found;
}
static void free_chosen_ports(void) {
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env != NULL) {
size_t i;
for (i = 0; i < num_chosen_ports; i++) {
grpc_free_port_using_server(env, chosen_ports[i]);
}
gpr_free(env);
size_t i;
for (i = 0; i < num_chosen_ports; i++) {
grpc_free_port_using_server(chosen_ports[i]);
}
gpr_free(chosen_ports);
}
@ -95,23 +93,27 @@ static void chose_port(int port) {
}
int grpc_pick_unused_port(void) {
// Currently only works with the port server
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
GPR_ASSERT(env);
int port = grpc_pick_port_using_server(env);
gpr_free(env);
int port = grpc_pick_port_using_server();
if (port != 0) {
chose_port(port);
}
return port;
}
int grpc_pick_unused_port_or_die(void) {
int port = grpc_pick_unused_port();
GPR_ASSERT(port > 0);
if (port == 0) {
fprintf(stderr,
"gRPC tests require a helper port server to allocate ports used \n"
"during the test.\n\n"
"This server is not currently running.\n\n"
"To start it, run tools/run_tests/start_port_server.py\n\n");
exit(1);
}
return port;
}
void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
#endif /* GRPC_UV && GRPC_TEST_PICK_PORT */
#endif /* GRPC_TEST_PICK_PORT */

@ -1,256 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/lib/iomgr/port.h"
#include "test/core/util/test_config.h"
#if defined(GRPC_POSIX_SOCKET) && defined(GRPC_TEST_PICK_PORT)
#include "test/core/util/port.h"
#include <errno.h>
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/support/env.h"
#include "test/core/util/port_server_client.h"
#define NUM_RANDOM_PORTS_TO_PICK 100
static int *chosen_ports = NULL;
static size_t num_chosen_ports = 0;
static int has_port_been_chosen(int port) {
size_t i;
for (i = 0; i < num_chosen_ports; i++) {
if (chosen_ports[i] == port) {
return 1;
}
}
return 0;
}
static int free_chosen_port(int port) {
size_t i;
int found = 0;
size_t found_at = 0;
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
/* Find the port and erase it from the list, then tell the server it can be
freed. */
for (i = 0; i < num_chosen_ports; i++) {
if (chosen_ports[i] == port) {
GPR_ASSERT(found == 0);
found = 1;
found_at = i;
}
}
if (found) {
chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1];
num_chosen_ports--;
if (env) {
grpc_free_port_using_server(env, port);
}
}
gpr_free(env);
return found;
}
static void free_chosen_ports(void) {
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env != NULL) {
size_t i;
for (i = 0; i < num_chosen_ports; i++) {
grpc_free_port_using_server(env, chosen_ports[i]);
}
gpr_free(env);
}
gpr_free(chosen_ports);
}
static void chose_port(int port) {
if (chosen_ports == NULL) {
atexit(free_chosen_ports);
}
num_chosen_ports++;
chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports);
chosen_ports[num_chosen_ports - 1] = port;
}
static bool is_port_available(int *port, bool is_tcp) {
GPR_ASSERT(*port >= 0);
GPR_ASSERT(*port <= 65535);
/* For a port to be considered available, the kernel must support
at least one of (IPv6, IPv4), and the port must be available
on each supported family. */
bool got_socket = false;
for (int is_ipv6 = 1; is_ipv6 >= 0; is_ipv6--) {
const int fd =
socket(is_ipv6 ? AF_INET6 : AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM,
is_tcp ? IPPROTO_TCP : 0);
if (fd >= 0) {
got_socket = true;
} else {
continue;
}
/* Reuseaddr lets us start up a server immediately after it exits */
const int one = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno));
close(fd);
return false;
}
/* Try binding to port */
grpc_resolved_address addr;
if (is_ipv6) {
grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */
} else {
grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */
}
if (bind(fd, (struct sockaddr *)addr.addr, (socklen_t)addr.len) < 0) {
gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
close(fd);
return false;
}
/* Get the bound port number */
if (getsockname(fd, (struct sockaddr *)addr.addr, (socklen_t *)&addr.len) <
0) {
gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
close(fd);
return false;
}
GPR_ASSERT(addr.len <= sizeof(addr.addr));
const int actual_port = grpc_sockaddr_get_port(&addr);
GPR_ASSERT(actual_port > 0);
if (*port == 0) {
*port = actual_port;
} else {
GPR_ASSERT(*port == actual_port);
}
close(fd);
}
if (!got_socket) {
gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno));
return false;
}
return true;
}
int grpc_pick_unused_port(void) {
/* We repeatedly pick a port and then see whether or not it is
available for use both as a TCP socket and a UDP socket. First, we
pick a random large port number. For subsequent
iterations, we bind to an anonymous port and let the OS pick the
port number. The random port picking reduces the probability of
races with other processes on kernels that want to reuse the same
port numbers over and over. */
/* In alternating iterations we trial UDP ports before TCP ports UDP
ports -- it could be the case that this machine has been using up
UDP ports and they are scarcer. */
/* Type of port to first pick in next iteration */
bool is_tcp = true;
int trial = 0;
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env) {
int port = grpc_pick_port_using_server(env);
gpr_free(env);
if (port != 0) {
chose_port(port);
}
return port;
}
for (;;) {
int port;
trial++;
if (trial == 1) {
port = getpid() % (65536 - 30000) + 30000;
} else if (trial <= NUM_RANDOM_PORTS_TO_PICK) {
port = rand() % (65536 - 30000) + 30000;
} else {
port = 0;
}
if (has_port_been_chosen(port)) {
continue;
}
if (!is_port_available(&port, is_tcp)) {
continue;
}
GPR_ASSERT(port > 0);
/* Check that the port # is free for the other type of socket also */
if (!is_port_available(&port, !is_tcp)) {
/* In the next iteration trial to bind to the other type first
because perhaps it is more rare. */
is_tcp = !is_tcp;
continue;
}
chose_port(port);
return port;
}
/* The port iterator reached the end without finding a suitable port. */
return 0;
}
int grpc_pick_unused_port_or_die(void) {
int port = grpc_pick_unused_port();
GPR_ASSERT(port > 0);
return port;
}
void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
#endif /* GRPC_POSIX_SOCKET && GRPC_TEST_PICK_PORT */

@ -74,7 +74,7 @@ static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_unlock(pr->mu);
}
void grpc_free_port_using_server(char *server, int port) {
void grpc_free_port_using_server(int port) {
grpc_httpcli_context context;
grpc_httpcli_request req;
grpc_httpcli_response rsp;
@ -95,7 +95,7 @@ void grpc_free_port_using_server(char *server, int port) {
shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops,
grpc_schedule_on_exec_ctx);
req.host = server;
req.host = GRPC_PORT_SERVER_ADDRESS;
gpr_asprintf(&path, "/drop/%d", port);
req.http.path = path;
@ -198,7 +198,7 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
gpr_mu_unlock(pr->mu);
}
int grpc_pick_port_using_server(char *server) {
int grpc_pick_port_using_server(void) {
grpc_httpcli_context context;
grpc_httpcli_request req;
portreq pr;
@ -215,10 +215,10 @@ int grpc_pick_port_using_server(char *server) {
shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops,
grpc_schedule_on_exec_ctx);
pr.port = -1;
pr.server = server;
pr.server = GRPC_PORT_SERVER_ADDRESS;
pr.ctx = &context;
req.host = server;
req.host = GRPC_PORT_SERVER_ADDRESS;
req.http.path = "/get";
grpc_httpcli_context_init(&context);

@ -36,7 +36,10 @@
// C interface to port_server.py
int grpc_pick_port_using_server(char *server);
void grpc_free_port_using_server(char *server, int port);
// must be synchronized with tools/run_tests/python_utils/start_port_server.py
#define GRPC_PORT_SERVER_ADDRESS "localhost:32766"
int grpc_pick_port_using_server(void);
void grpc_free_port_using_server(int port);
#endif // GRPC_TEST_CORE_UTIL_PORT_SERVER_CLIENT_H

@ -1,247 +0,0 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "src/core/lib/iomgr/port.h"
#include "test/core/util/test_config.h"
#if defined(GRPC_WINSOCK_SOCKET) && defined(GRPC_TEST_PICK_PORT)
#include "src/core/lib/iomgr/sockaddr.h"
#include "test/core/util/port.h"
#include <errno.h>
#include <process.h>
#include <stdio.h>
#include <string.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/core/lib/support/env.h"
#include "test/core/util/port_server_client.h"
#if GPR_GETPID_IN_UNISTD_H
#include <sys/unistd.h>
static int _getpid() { return getpid(); }
#endif
#define NUM_RANDOM_PORTS_TO_PICK 100
static int *chosen_ports = NULL;
static size_t num_chosen_ports = 0;
static int has_port_been_chosen(int port) {
size_t i;
for (i = 0; i < num_chosen_ports; i++) {
if (chosen_ports[i] == port) {
return 1;
}
}
return 0;
}
static int free_chosen_port(int port) {
size_t i;
int found = 0;
size_t found_at = 0;
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env != NULL) {
/* Find the port and erase it from the list, then tell the server it can be
freed. */
for (i = 0; i < num_chosen_ports; i++) {
if (chosen_ports[i] == port) {
GPR_ASSERT(found == 0);
found = 1;
found_at = i;
}
}
if (found) {
chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1];
grpc_free_port_using_server(env, port);
num_chosen_ports--;
}
}
return found;
}
static void free_chosen_ports(void) {
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env != NULL) {
size_t i;
for (i = 0; i < num_chosen_ports; i++) {
grpc_free_port_using_server(env, chosen_ports[i]);
}
gpr_free(env);
}
gpr_free(chosen_ports);
}
static void chose_port(int port) {
if (chosen_ports == NULL) {
atexit(free_chosen_ports);
}
num_chosen_ports++;
chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports);
chosen_ports[num_chosen_ports - 1] = port;
}
static int is_port_available(int *port, int is_tcp) {
const int proto = is_tcp ? IPPROTO_TCP : 0;
const SOCKET fd = socket(AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, proto);
int one = 1;
struct sockaddr_in addr;
socklen_t alen = sizeof(addr);
int actual_port;
GPR_ASSERT(*port >= 0);
GPR_ASSERT(*port <= 65535);
if (INVALID_SOCKET == fd) {
gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno));
return 0;
}
/* Reuseaddr lets us start up a server immediately after it exits */
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one,
sizeof(one)) < 0) {
gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno));
closesocket(fd);
return 0;
}
/* Try binding to port */
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons((u_short)*port);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
closesocket(fd);
return 0;
}
/* Get the bound port number */
if (getsockname(fd, (struct sockaddr *)&addr, &alen) < 0) {
gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
closesocket(fd);
return 0;
}
GPR_ASSERT(alen <= (socklen_t)sizeof(addr));
actual_port = ntohs(addr.sin_port);
GPR_ASSERT(actual_port > 0);
if (*port == 0) {
*port = actual_port;
} else {
GPR_ASSERT(*port == actual_port);
}
closesocket(fd);
return 1;
}
int grpc_pick_unused_port(void) {
/* We repeatedly pick a port and then see whether or not it is
available for use both as a TCP socket and a UDP socket. First, we
pick a random large port number. For subsequent
iterations, we bind to an anonymous port and let the OS pick the
port number. The random port picking reduces the probability of
races with other processes on kernels that want to reuse the same
port numbers over and over. */
/* In alternating iterations we trial UDP ports before TCP ports UDP
ports -- it could be the case that this machine has been using up
UDP ports and they are scarcer. */
/* Type of port to first pick in next iteration */
int is_tcp = 1;
int trial = 0;
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env) {
int port = grpc_pick_port_using_server(env);
gpr_free(env);
if (port != 0) {
return port;
}
}
for (;;) {
int port;
trial++;
if (trial == 1) {
port = _getpid() % (65536 - 30000) + 30000;
} else if (trial <= NUM_RANDOM_PORTS_TO_PICK) {
port = rand() % (65536 - 30000) + 30000;
} else {
port = 0;
}
if (has_port_been_chosen(port)) {
continue;
}
if (!is_port_available(&port, is_tcp)) {
continue;
}
GPR_ASSERT(port > 0);
/* Check that the port # is free for the other type of socket also */
if (!is_port_available(&port, !is_tcp)) {
/* In the next iteration trial to bind to the other type first
because perhaps it is more rare. */
is_tcp = !is_tcp;
continue;
}
/* TODO(ctiller): consider caching this port in some structure, to avoid
handing it out again */
chose_port(port);
return port;
}
/* The port iterator reached the end without finding a suitable port. */
return 0;
}
int grpc_pick_unused_port_or_die(void) {
int port = grpc_pick_unused_port();
GPR_ASSERT(port > 0);
return port;
}
void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
#endif /* GRPC_WINSOCK_SOCKET && GRPC_TEST_PICK_PORT */

@ -1,4 +1,4 @@
// Generated by the gRPC protobuf plugin.
// Generated by the gRPC C++ plugin.
// If you make any local change, they will be lost.
// source: src/proto/grpc/testing/compiler_test.proto
// Original file comments:

@ -65,7 +65,9 @@ Http2Client::ServiceStub::ServiceStub(std::shared_ptr<Channel> channel)
TestService::Stub* Http2Client::ServiceStub::Get() { return stub_.get(); }
Http2Client::Http2Client(std::shared_ptr<Channel> channel)
: serviceStub_(channel), channel_(channel) {}
: serviceStub_(channel),
channel_(channel),
defaultRequest_(BuildDefaultRequest()) {}
bool Http2Client::AssertStatusCode(const Status& s, StatusCode expected_code) {
if (s.error_code() == expected_code) {
@ -77,18 +79,24 @@ bool Http2Client::AssertStatusCode(const Status& s, StatusCode expected_code) {
abort();
}
bool Http2Client::DoRstAfterHeader() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header");
Status Http2Client::SendUnaryCall(SimpleResponse* response) {
ClientContext context;
return serviceStub_.Get()->UnaryCall(&context, defaultRequest_, response);
}
SimpleRequest Http2Client::BuildDefaultRequest() {
SimpleRequest request;
SimpleResponse response;
request.set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
return request;
}
bool Http2Client::DoRstAfterHeader() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header");
Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
AssertStatusCode(s, grpc::StatusCode::UNKNOWN);
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
GPR_ASSERT(!response.has_payload()); // no data should be received
gpr_log(GPR_DEBUG, "Done testing reset stream after header");
@ -98,15 +106,8 @@ bool Http2Client::DoRstAfterHeader() {
bool Http2Client::DoRstAfterData() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after data");
ClientContext context;
SimpleRequest request;
SimpleResponse response;
request.set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
AssertStatusCode(s, grpc::StatusCode::UNKNOWN);
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
GPR_ASSERT(response.has_payload()); // data should be received
gpr_log(GPR_DEBUG, "Done testing reset stream after data");
@ -116,15 +117,8 @@ bool Http2Client::DoRstAfterData() {
bool Http2Client::DoRstDuringData() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream during data");
ClientContext context;
SimpleRequest request;
SimpleResponse response;
request.set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
AssertStatusCode(s, grpc::StatusCode::UNKNOWN);
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
GPR_ASSERT(!response.has_payload()); // no data should be received
gpr_log(GPR_DEBUG, "Done testing reset stream during data");
@ -133,56 +127,37 @@ bool Http2Client::DoRstDuringData() {
bool Http2Client::DoGoaway() {
gpr_log(GPR_DEBUG, "Sending two RPCs and expecting goaway");
SimpleResponse response;
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
GPR_ASSERT(response.payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
int numCalls = 2;
for (int i = 0; i < numCalls; i++) {
ClientContext context;
SimpleRequest request;
SimpleResponse response;
request.set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
AssertStatusCode(s, grpc::StatusCode::OK);
GPR_ASSERT(response.payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
}
// Sleep for one second to give time for client to receive goaway frame.
gpr_timespec sleep_time = gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(1, GPR_TIMESPAN));
gpr_sleep_until(sleep_time);
response.Clear();
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
GPR_ASSERT(response.payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
gpr_log(GPR_DEBUG, "Done testing goaway");
return true;
}
bool Http2Client::DoPing() {
gpr_log(GPR_DEBUG, "Sending RPC and expecting ping");
ClientContext context;
SimpleRequest request;
SimpleResponse response;
request.set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s = serviceStub_.Get()->UnaryCall(&context, request, &response);
AssertStatusCode(s, grpc::StatusCode::OK);
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
GPR_ASSERT(response.payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
gpr_log(GPR_DEBUG, "Done testing ping");
return true;
}
void Http2Client::MaxStreamsWorker(std::shared_ptr<grpc::Channel> channel) {
ClientContext context;
SimpleRequest request;
SimpleResponse response;
request.set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s =
TestService::NewStub(channel)->UnaryCall(&context, request, &response);
AssertStatusCode(s, grpc::StatusCode::OK);
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
GPR_ASSERT(response.payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
}
@ -192,15 +167,8 @@ bool Http2Client::DoMaxStreams() {
// Make an initial call on the channel to ensure the server's max streams
// setting is received
ClientContext context;
SimpleRequest request;
SimpleResponse response;
request.set_response_size(kLargeResponseSize);
grpc::string payload(kLargeRequestSize, '\0');
request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
Status s =
TestService::NewStub(channel_)->UnaryCall(&context, request, &response);
AssertStatusCode(s, grpc::StatusCode::OK);
AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
GPR_ASSERT(response.payload().body() ==
grpc::string(kLargeResponseSize, '\0'));
@ -240,7 +208,11 @@ int main(int argc, char** argv) {
char host_port[host_port_buf_size];
snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
FLAGS_server_port);
grpc::testing::Http2Client client(grpc::CreateTestChannel(host_port, false));
std::shared_ptr<grpc::Channel> channel =
grpc::CreateTestChannel(host_port, false);
GPR_ASSERT(channel->WaitForConnected(gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN))));
grpc::testing::Http2Client client(channel);
gpr_log(GPR_INFO, "Testing case: %s", FLAGS_test_case.c_str());
int ret = 0;
if (FLAGS_test_case == "rst_after_header") {

@ -70,8 +70,11 @@ class Http2Client {
void MaxStreamsWorker(std::shared_ptr<grpc::Channel> channel);
bool AssertStatusCode(const Status& s, StatusCode expected_code);
Status SendUnaryCall(SimpleResponse* response);
SimpleRequest BuildDefaultRequest();
ServiceStub serviceStub_;
std::shared_ptr<Channel> channel_;
SimpleRequest defaultRequest_;
};
} // namespace testing

@ -62,21 +62,48 @@ static struct Init {
~Init() { grpc_shutdown(); }
} g_init;
static void BM_InsecureChannelWithDefaults(benchmark::State &state) {
grpc_channel *channel =
grpc_insecure_channel_create("localhost:12345", NULL, NULL);
class BaseChannelFixture {
public:
BaseChannelFixture(grpc_channel *channel) : channel_(channel) {}
~BaseChannelFixture() { grpc_channel_destroy(channel_); }
grpc_channel *channel() const { return channel_; }
private:
grpc_channel *const channel_;
};
class InsecureChannel : public BaseChannelFixture {
public:
InsecureChannel()
: BaseChannelFixture(
grpc_insecure_channel_create("localhost:1234", NULL, NULL)) {}
};
class LameChannel : public BaseChannelFixture {
public:
LameChannel()
: BaseChannelFixture(grpc_lame_client_channel_create(
"localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah")) {}
};
template <class Fixture>
static void BM_CallCreateDestroy(benchmark::State &state) {
Fixture fixture;
grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
grpc_slice method = grpc_slice_from_static_string("/foo/bar");
gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
void *method_hdl =
grpc_channel_register_call(fixture.channel(), "/foo/bar", NULL, NULL);
while (state.KeepRunning()) {
grpc_call_destroy(grpc_channel_create_call(channel, NULL,
GRPC_PROPAGATE_DEFAULTS, cq,
method, NULL, deadline, NULL));
grpc_call_destroy(grpc_channel_create_registered_call(
fixture.channel(), NULL, GRPC_PROPAGATE_DEFAULTS, cq, method_hdl,
deadline, NULL));
}
grpc_channel_destroy(channel);
grpc_completion_queue_destroy(cq);
}
BENCHMARK(BM_InsecureChannelWithDefaults);
BENCHMARK_TEMPLATE(BM_CallCreateDestroy, InsecureChannel);
BENCHMARK_TEMPLATE(BM_CallCreateDestroy, LameChannel);
static void FilterDestroy(grpc_exec_ctx *exec_ctx, void *arg,
grpc_error *error) {

@ -36,8 +36,10 @@
#include <grpc/grpc.h>
extern "C" {
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/transport.h"
}
#include "third_party/benchmark/include/benchmark/benchmark.h"
@ -62,6 +64,19 @@ static void BM_SliceFromCopied(benchmark::State& state) {
}
BENCHMARK(BM_SliceFromCopied);
static void BM_SliceFromStreamOwnedBuffer(benchmark::State& state) {
grpc_stream_refcount r;
GRPC_STREAM_REF_INIT(&r, 1, NULL, NULL, "test");
char buffer[64];
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
while (state.KeepRunning()) {
grpc_slice_unref_internal(&exec_ctx, grpc_slice_from_stream_owned_buffer(
&r, buffer, sizeof(buffer)));
}
grpc_exec_ctx_finish(&exec_ctx);
}
BENCHMARK(BM_SliceFromStreamOwnedBuffer);
static void BM_SliceIntern(benchmark::State& state) {
gpr_slice slice = grpc_slice_from_static_string("abc");
while (state.KeepRunning()) {

@ -47,3 +47,6 @@ make install-certs
# build C++ interop client & server
make interop_client interop_server
# build C++ http2 client
make http2_client

@ -786,6 +786,7 @@ doc/naming.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/server_reflection_tutorial.md \
doc/server_side_auth.md \
doc/service_config.md \
doc/statuscodes.md \
doc/stress_test_framework.md \

@ -786,6 +786,7 @@ doc/naming.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/server_reflection_tutorial.md \
doc/server_side_auth.md \
doc/service_config.md \
doc/statuscodes.md \
doc/stress_test_framework.md \

@ -785,6 +785,7 @@ doc/naming.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/server_reflection_tutorial.md \
doc/server_side_auth.md \
doc/service_config.md \
doc/statuscodes.md \
doc/stress_test_framework.md \

@ -785,6 +785,7 @@ doc/naming.md \
doc/negative-http2-interop-test-descriptions.md \
doc/server-reflection.md \
doc/server_reflection_tutorial.md \
doc/server_side_auth.md \
doc/service_config.md \
doc/statuscodes.md \
doc/stress_test_framework.md \

@ -142,7 +142,7 @@ gem install bundler
# Significant performance improvements with grpc-go have been observed after
# upgrading from go 1.5 to a later version, so a later go version is preferred.
# Following go install instructions from https://golang.org/doc/install
GO_VERSION=1.7.1
GO_VERSION=1.8
OS=linux
ARCH=amd64
curl -O https://storage.googleapis.com/golang/go${GO_VERSION}.${OS}-${ARCH}.tar.gz

@ -27,18 +27,17 @@
@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
setlocal
@rem make sure msys binaries are preferred over cygwin binaries
@rem set path to python 2.7
set PATH=C:\tools\msys64\usr\bin;C:\Python27;%PATH%
@rem enter repo root
cd /d %~dp0\..\..\..
git submodule update --init
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x c_windows_dbg_sponge_log.xml --report_suite_name c_windows_dbg -l c -c dbg
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x c_windows_opt_sponge_log.xml --report_suite_name c_windows_opt -l c -c opt
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x csharp_windows_dbg_sponge_log.xml --report_suite_name csharp_windows_dbg -l csharp -c dbg
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x csharp_windows_opt_sponge_log.xml --report_suite_name csharp_windows_opt -l csharp -c opt
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x node_windows_dbg_sponge_log.xml --report_suite_name node_windows_dbg -l node -c dbg
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x node_windows_opt_sponge_log.xml --report_suite_name node_windows_opt -l node -c opt
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x python_windows_dbg_sponge_log.xml --report_suite_name python_windows_dbg -l python -c dbg
sh tools\run_tests\helper_scripts\run_tests_in_workspace.sh -t -j 4 -x python_windows_opt_sponge_log.xml --report_suite_name python_windows_opt -l python -c opt
python tools/run_tests/run_tests_matrix.py -f basictests windows -j 1 --inner_jobs 8 || goto :error
goto :EOF
:error
exit /b %errorlevel%

@ -0,0 +1,73 @@
#!/usr/bin/env bash
# Copyright 2017, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# A frozen version of run_full_performance.sh that runs full performance test
# suite for the latest released stable version of gRPC.
set -ex
# Enter the gRPC repo root
cd $(dirname $0)/../..
# run 8core client vs 8core server
tools/run_tests/run_performance_tests.py \
-l c++ csharp node ruby java python go node_express \
--netperf \
--category scalable \
--bq_result_table performance_released.performance_experiment \
--remote_worker_host grpc-performance-server-8core grpc-performance-client-8core grpc-performance-client2-8core \
--xml_report report_8core.xml \
|| EXIT_CODE=1
# prevent pushing leftover build files to remote hosts in the next step.
git clean -fdxq --exclude='report*.xml'
# scalability with 32cores (and upload to a different BQ table)
tools/run_tests/run_performance_tests.py \
-l c++ java csharp go \
--netperf \
--category scalable \
--bq_result_table performance_released.performance_experiment_32core \
--remote_worker_host grpc-performance-server-32core grpc-performance-client-32core grpc-performance-client2-32core \
--xml_report report_32core.xml \
|| EXIT_CODE=1
# prevent pushing leftover build files to remote hosts in the next step.
git clean -fdxq --exclude='report*.xml'
# selected scenarios on Windows
tools/run_tests/run_performance_tests.py \
-l csharp \
--category scalable \
--bq_result_table performance_released.performance_experiment_windows \
--remote_worker_host grpc-performance-windows1 grpc-performance-windows2 \
--xml_report report_windows.xml \
|| EXIT_CODE=1
exit $EXIT_CODE

@ -88,7 +88,145 @@ else:
writer = csv.DictWriter(sys.stdout, [c for c,t in columns])
<<<<<<< HEAD
for row in bm_json.expand_json(js, js2):
=======
bm_specs = {
'BM_UnaryPingPong': {
'tpl': ['fixture', 'client_mutator', 'server_mutator'],
'dyn': ['request_size', 'response_size'],
},
'BM_PumpStreamClientToServer': {
'tpl': ['fixture'],
'dyn': ['request_size'],
},
'BM_PumpStreamServerToClient': {
'tpl': ['fixture'],
'dyn': ['request_size'],
},
'BM_StreamingPingPong': {
'tpl': ['fixture', 'client_mutator', 'server_mutator'],
'dyn': ['request_size', 'request_count'],
},
'BM_StreamingPingPongMsgs': {
'tpl': ['fixture', 'client_mutator', 'server_mutator'],
'dyn': ['request_size'],
},
'BM_PumpStreamServerToClient_Trickle': {
'tpl': [],
'dyn': ['request_size', 'bandwidth_kilobits'],
},
'BM_ErrorStringOnNewError': {
'tpl': ['fixture'],
'dyn': [],
},
'BM_ErrorStringRepeatedly': {
'tpl': ['fixture'],
'dyn': [],
},
'BM_ErrorGetStatus': {
'tpl': ['fixture'],
'dyn': [],
},
'BM_ErrorGetStatusCode': {
'tpl': ['fixture'],
'dyn': [],
},
'BM_ErrorHttpError': {
'tpl': ['fixture'],
'dyn': [],
},
'BM_HasClearGrpcStatus': {
'tpl': ['fixture'],
'dyn': [],
},
'BM_IsolatedFilter' : {
'tpl': ['fixture', 'client_mutator'],
'dyn': [],
},
'BM_HpackEncoderEncodeHeader' : {
'tpl': ['fixture'],
'dyn': ['end_of_stream', 'request_size'],
},
'BM_HpackParserParseHeader' : {
'tpl': ['fixture'],
'dyn': [],
},
'BM_CallCreateDestroy' : {
'tpl': ['fixture'],
'dyn': [],
},
}
def numericalize(s):
if not s: return ''
if s[-1] == 'k':
return int(s[:-1]) * 1024
if s[-1] == 'M':
return int(s[:-1]) * 1024 * 1024
if 0 <= (ord(s[-1]) - ord('0')) <= 9:
return int(s)
assert 'not a number: %s' % s
def parse_name(name):
if '<' not in name and '/' not in name and name not in bm_specs:
return {'name': name}
rest = name
out = {}
tpl_args = []
dyn_args = []
if '<' in rest:
tpl_bit = rest[rest.find('<') + 1 : rest.rfind('>')]
arg = ''
nesting = 0
for c in tpl_bit:
if c == '<':
nesting += 1
arg += c
elif c == '>':
nesting -= 1
arg += c
elif c == ',':
if nesting == 0:
tpl_args.append(arg.strip())
arg = ''
else:
arg += c
else:
arg += c
tpl_args.append(arg.strip())
rest = rest[:rest.find('<')] + rest[rest.rfind('>') + 1:]
if '/' in rest:
s = rest.split('/')
rest = s[0]
dyn_args = s[1:]
name = rest
assert name in bm_specs, 'bm_specs needs to be expanded for %s' % name
assert len(dyn_args) == len(bm_specs[name]['dyn'])
assert len(tpl_args) == len(bm_specs[name]['tpl'])
out['name'] = name
out.update(dict((k, numericalize(v)) for k, v in zip(bm_specs[name]['dyn'], dyn_args)))
out.update(dict(zip(bm_specs[name]['tpl'], tpl_args)))
return out
for bm in js['benchmarks']:
context = js['context']
if 'label' in bm:
labels_list = [s.split(':') for s in bm['label'].strip().split(' ') if len(s) and s[0] != '#']
for el in labels_list:
el[0] = el[0].replace('/iter', '_per_iteration')
labels = dict(labels_list)
else:
labels = {}
row = {
'jenkins_build': os.environ.get('BUILD_NUMBER', ''),
'jenkins_job': os.environ.get('JOB_NAME', ''),
}
row.update(context)
row.update(bm)
row.update(parse_name(row['name']))
row.update(labels)
>>>>>>> cf54c151f1853af1fe1df2058ccbc2ca3a26c43c
if 'label' in row:
del row['label']
del row['cpp_name']

@ -90,6 +90,10 @@ _BM_SPECS = {
'tpl': ['fixture'],
'dyn': [],
},
'BM_CallCreateDestroy' : {
'tpl': ['fixture'],
'dyn': [],
},
}
def numericalize(s):
@ -170,4 +174,3 @@ def expand_json(js, js2 = None):
row['real_time'] = bm2['real_time']
row['iterations'] = bm2['iterations']
yield row

@ -1657,6 +1657,23 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "parse_address_test",
"src": [
"test/core/client_channel/parse_address_test.c"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -2032,6 +2049,23 @@
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
"gpr_test_util",
"grpc",
"grpc_test_util"
],
"headers": [],
"is_filegroup": false,
"language": "c",
"name": "stream_owned_slice_test",
"src": [
"test/core/transport/stream_owned_slice_test.c"
],
"third_party": false,
"type": "target"
},
{
"deps": [
"gpr",
@ -7952,12 +7986,10 @@
"test/core/util/parse_hexstring.h",
"test/core/util/passthru_endpoint.c",
"test/core/util/passthru_endpoint.h",
"test/core/util/port.c",
"test/core/util/port.h",
"test/core/util/port_posix.c",
"test/core/util/port_server_client.c",
"test/core/util/port_server_client.h",
"test/core/util/port_uv.c",
"test/core/util/port_windows.c",
"test/core/util/slice_splitter.c",
"test/core/util/slice_splitter.h",
"test/core/util/trickle_endpoint.c",

@ -1719,6 +1719,28 @@
"windows"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "parse_address_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [
@ -2115,6 +2137,28 @@
"windows"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": false,
"language": "c",
"name": "stream_owned_slice_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [
@ -80560,6 +80604,28 @@
],
"uses_polling": false
},
{
"args": [
"test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448"
],
"ci_platforms": [
"linux"
],
"cpu_cost": 0.1,
"exclude_configs": [
"tsan"
],
"exclude_iomgrs": [
"uv"
],
"flaky": false,
"language": "c",
"name": "api_fuzzer_one_entry",
"platforms": [
"linux"
],
"uses_polling": false
},
{
"args": [
"test/core/end2end/fuzzers/api_fuzzer_corpus/crash-0597bbdd657fa4ed14443994c9147a1a7bbc205f"

@ -413,11 +413,12 @@ class NodeLanguage:
client_type='ASYNC_CLIENT', server_type='async_server',
client_language='c++')
yield _ping_pong_scenario(
'node_protobuf_async_unary_qps_unconstrained', rpc_type='UNARY',
client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
unconstrained_client='async',
categories=[SCALABLE, SMOKETEST])
# TODO(murgatroid99): fix bugs with this scenario and re-enable it
# yield _ping_pong_scenario(
# 'node_protobuf_async_unary_qps_unconstrained', rpc_type='UNARY',
# client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
# unconstrained_client='async',
# categories=[SCALABLE, SMOKETEST])
# TODO(jtattermusch): make this scenario work
#yield _ping_pong_scenario(

@ -40,7 +40,10 @@ import tempfile
import time
def start_port_server(port_server_port):
# must be synchronized with test/core/utils/port_server_client.h
_PORT_SERVER_PORT = 32766
def start_port_server():
# check if a compatible port server is running
# if incompatible (version mismatch) ==> start a new one
# if not running ==> start a new one
@ -48,7 +51,7 @@ def start_port_server(port_server_port):
try:
version = int(
urllib.request.urlopen(
'http://localhost:%d/version_number' % port_server_port,
'http://localhost:%d/version_number' % _PORT_SERVER_PORT,
timeout=10).read())
logging.info('detected port server running version %d', version)
running = True
@ -67,7 +70,7 @@ def start_port_server(port_server_port):
if not running:
logging.info('port_server version mismatch: killing the old one')
urllib.request.urlopen('http://localhost:%d/quitquitquit' %
port_server_port).read()
_PORT_SERVER_PORT).read()
time.sleep(1)
if not running:
fd, logfile = tempfile.mkstemp()
@ -76,7 +79,7 @@ def start_port_server(port_server_port):
args = [
sys.executable,
os.path.abspath('tools/run_tests/python_utils/port_server.py'),
'-p', '%d' % port_server_port, '-l', logfile
'-p', '%d' % _PORT_SERVER_PORT, '-l', logfile
]
env = dict(os.environ)
env['BUILD_ID'] = 'pleaseDontKillMeJenkins'
@ -107,7 +110,7 @@ def start_port_server(port_server_port):
time.sleep(1)
try:
urllib.request.urlopen(
'http://localhost:%d/get' % port_server_port,
'http://localhost:%d/get' % _PORT_SERVER_PORT,
timeout=1).read()
logging.info(
'last ditch attempt to contact port server succeeded')
@ -119,7 +122,7 @@ def start_port_server(port_server_port):
print(port_log)
sys.exit(1)
try:
port_server_url = 'http://localhost:%d/get' % port_server_port
port_server_url = 'http://localhost:%d/get' % _PORT_SERVER_PORT
urllib.request.urlopen(port_server_url, timeout=1).read()
logging.info('port server is up and ready')
break

@ -77,11 +77,15 @@ class CXXLanguage:
def __init__(self):
self.client_cwd = None
self.server_cwd = None
self.http2_cwd = None
self.safename = 'cxx'
def client_cmd(self, args):
return ['bins/opt/interop_client'] + args
def client_cmd_http2interop(self, args):
return ['bins/opt/http2_client'] + args
def cloud_to_prod_env(self):
return {}
@ -474,7 +478,7 @@ _HTTP2_TEST_CASES = ['tls', 'framing']
_HTTP2_BADSERVER_TEST_CASES = ['rst_after_header', 'rst_after_data', 'rst_during_data',
'goaway', 'ping', 'max_streams']
_LANGUAGES_FOR_HTTP2_BADSERVER_TESTS = ['java', 'go', 'python']
_LANGUAGES_FOR_HTTP2_BADSERVER_TESTS = ['java', 'go', 'python', 'c++']
DOCKER_WORKDIR_ROOT = '/var/local/git/grpc'

@ -44,8 +44,7 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
if not os.path.exists('reports'):
os.makedirs('reports')
port_server_port = 32766
start_port_server.start_port_server(port_server_port)
start_port_server.start_port_server()
def fnize(s):
out = ''
@ -110,8 +109,7 @@ def collect_latency(bm_name, args):
if len(benchmarks) >= min(16, multiprocessing.cpu_count()):
# run up to half the cpu count: each benchmark can use up to two cores
# (one for the microbenchmark, one for the data flush)
jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2),
add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2))
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
benchmarks = []
@ -119,8 +117,7 @@ def collect_latency(bm_name, args):
cleanup = []
# run the remaining benchmarks that weren't flushed
if len(benchmarks):
jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2),
add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2))
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
@ -156,8 +153,7 @@ def collect_perf(bm_name, args):
if len(benchmarks) >= 20:
# run up to half the cpu count: each benchmark can use up to two cores
# (one for the microbenchmark, one for the data flush)
jobset.run(benchmarks, maxjobs=1,
add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
jobset.run(benchmarks, maxjobs=1)
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
benchmarks = []
@ -165,8 +161,7 @@ def collect_perf(bm_name, args):
cleanup = []
# run the remaining benchmarks that weren't flushed
if len(benchmarks):
jobset.run(benchmarks, maxjobs=1,
add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
jobset.run(benchmarks, maxjobs=1)
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())

@ -692,18 +692,11 @@ class RubyLanguage(object):
_check_compiler(self.args.compiler, ['default'])
def test_specs(self):
#TODO(apolcyn) turn mac ruby tests back on once ruby 2.4 issues done
if platform_string() == 'mac':
print('skipping ruby test_specs on mac until running on 2.4')
return []
return [self.config.job_spec(['tools/run_tests/helper_scripts/run_ruby.sh'],
timeout_seconds=10*60,
environ=_FORCE_ENVIRON_FOR_WRAPPERS)]
def pre_build_steps(self):
if platform_string() == 'mac':
print('skipping ruby pre_build_steps on mac until running on 2.4')
return []
return [['tools/run_tests/helper_scripts/pre_build_ruby.sh']]
def make_targets(self):
@ -713,15 +706,9 @@ class RubyLanguage(object):
return []
def build_steps(self):
if platform_string() == 'mac':
print('skipping ruby build_steps on mac until running on 2.4')
return []
return [['tools/run_tests/helper_scripts/build_ruby.sh']]
def post_tests_steps(self):
if platform_string() == 'mac':
print('skipping ruby post_test_steps on mac until running on 2.4')
return []
return [['tools/run_tests/helper_scripts/post_tests_ruby.sh']]
def makefile_name(self):
@ -1451,8 +1438,7 @@ def _build_and_run(
# start antagonists
antagonists = [subprocess.Popen(['tools/run_tests/python_utils/antagonist.py'])
for _ in range(0, args.antagonists)]
port_server_port = 32766
start_port_server.start_port_server(port_server_port)
start_port_server.start_port_server()
resultset = None
num_test_failures = 0
try:
@ -1495,7 +1481,6 @@ def _build_and_run(
all_runs, check_cancelled, newline_on_success=newline_on_success,
travis=args.travis, maxjobs=args.jobs,
stop_on_failure=args.stop_on_failure,
add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port},
quiet_success=args.quiet_success)
if resultset:
for k, v in sorted(resultset.items()):

@ -70,7 +70,8 @@ def _workspace_jobspec(name, runtests_args=[], workspace_name=None, inner_jobs=_
workspace_name = 'workspace_%s' % name
env = {'WORKSPACE_NAME': workspace_name}
test_job = jobset.JobSpec(
cmdline=['tools/run_tests/helper_scripts/run_tests_in_workspace.sh',
cmdline=['bash',
'tools/run_tests/helper_scripts/run_tests_in_workspace.sh',
'-t',
'-j', str(inner_jobs),
'-x', '../report_%s.xml' % name,

@ -0,0 +1,46 @@
#!/usr/bin/env python
# Copyright 2017, 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.
"""
Wrapper around port server starting code.
Used by developers who wish to run individual C/C++ tests outside of the
run_tests.py infrastructure.
The path to this file is called out in test/core/util/port.c, and printed as
an error message to users.
"""
import python_utils.start_port_server as start_port_server
start_port_server.start_port_server()
print "Port server started successfully"

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save